diff options
34 files changed, 104 insertions, 30 deletions
diff --git a/app/controllers/projects/pages_controller.rb b/app/controllers/projects/pages_controller.rb index cae6e2c40b8..ff49911d892 100644 --- a/app/controllers/projects/pages_controller.rb +++ b/app/controllers/projects/pages_controller.rb @@ -11,7 +11,7 @@ class Projects::PagesController < Projects::ApplicationController def destroy project.remove_pages - project.pages_domains.destroy_all + project.pages_domains.destroy_all # rubocop: disable DestroyAll respond_to do |format| format.html do diff --git a/app/models/concerns/awardable.rb b/app/models/concerns/awardable.rb index dd07f389fa5..49981db0d80 100644 --- a/app/models/concerns/awardable.rb +++ b/app/models/concerns/awardable.rb @@ -101,7 +101,7 @@ module Awardable end def remove_award_emoji(name, current_user) - award_emoji.where(name: name, user: current_user).destroy_all + award_emoji.where(name: name, user: current_user).destroy_all # rubocop: disable DestroyAll end def toggle_award_emoji(emoji_name, current_user) diff --git a/app/models/concerns/fast_destroy_all.rb b/app/models/concerns/fast_destroy_all.rb index 65ed46ea202..c342d01243e 100644 --- a/app/models/concerns/fast_destroy_all.rb +++ b/app/models/concerns/fast_destroy_all.rb @@ -34,7 +34,7 @@ module FastDestroyAll included do before_destroy do - raise ForbiddenActionError, '`destroy` and `destroy_all` are forbbiden. Please use `fast_destroy_all`' + raise ForbiddenActionError, '`destroy` and `destroy_all` are forbidden. Please use `fast_destroy_all`' end end diff --git a/app/models/lfs_object.rb b/app/models/lfs_object.rb index 2a1a4ef48b7..97bf5d611c2 100644 --- a/app/models/lfs_object.rb +++ b/app/models/lfs_object.rb @@ -29,11 +29,13 @@ class LfsObject < ActiveRecord::Base [nil, LfsObjectUploader::Store::LOCAL].include?(self.file_store) end + # rubocop: disable DestroyAll def self.destroy_unreferenced joins("LEFT JOIN lfs_objects_projects ON lfs_objects_projects.lfs_object_id = #{table_name}.id") .where(lfs_objects_projects: { id: nil }) .destroy_all end + # rubocop: enable DestroyAll def self.calculate_oid(path) Digest::SHA256.file(path).hexdigest diff --git a/app/models/user.rb b/app/models/user.rb index fb19de4b980..13b04270a4a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -516,7 +516,7 @@ class User < ActiveRecord::Base otp_grace_period_started_at: nil, otp_backup_codes: nil ) - self.u2f_registrations.destroy_all + self.u2f_registrations.destroy_all # rubocop: disable DestroyAll end end diff --git a/app/services/labels/promote_service.rb b/app/services/labels/promote_service.rb index c0463052821..623a5f0950e 100644 --- a/app/services/labels/promote_service.rb +++ b/app/services/labels/promote_service.rb @@ -65,7 +65,7 @@ module Labels end def update_project_labels(label_ids) - Label.where(id: label_ids).destroy_all + Label.where(id: label_ids).destroy_all # rubocop: disable DestroyAll end def clone_label_to_group_label(label) diff --git a/app/services/milestones/promote_service.rb b/app/services/milestones/promote_service.rb index 37aa6d3a9bc..660b4faaec0 100644 --- a/app/services/milestones/promote_service.rb +++ b/app/services/milestones/promote_service.rb @@ -73,7 +73,7 @@ module Milestones end def destroy_old_milestones(milestone) - Milestone.where(id: milestone_ids_for_merge(milestone)).destroy_all + Milestone.where(id: milestone_ids_for_merge(milestone)).destroy_all # rubocop: disable DestroyAll end def group_project_ids diff --git a/app/services/projects/move_deploy_keys_projects_service.rb b/app/services/projects/move_deploy_keys_projects_service.rb index 40a22837eaf..9f3f44f30ea 100644 --- a/app/services/projects/move_deploy_keys_projects_service.rb +++ b/app/services/projects/move_deploy_keys_projects_service.rb @@ -27,7 +27,7 @@ module Projects end def remove_remaining_deploy_keys_projects - source_project.deploy_keys_projects.destroy_all + source_project.deploy_keys_projects.destroy_all # rubocop: disable DestroyAll end end end diff --git a/app/services/projects/move_lfs_objects_projects_service.rb b/app/services/projects/move_lfs_objects_projects_service.rb index a5099519594..f78546a1e9c 100644 --- a/app/services/projects/move_lfs_objects_projects_service.rb +++ b/app/services/projects/move_lfs_objects_projects_service.rb @@ -21,7 +21,7 @@ module Projects end def remove_remaining_lfs_objects_project - source_project.lfs_objects_projects.destroy_all + source_project.lfs_objects_projects.destroy_all # rubocop: disable DestroyAll end def non_existent_lfs_objects_projects diff --git a/app/services/projects/move_notification_settings_service.rb b/app/services/projects/move_notification_settings_service.rb index 746605d56f1..109a00dd6d9 100644 --- a/app/services/projects/move_notification_settings_service.rb +++ b/app/services/projects/move_notification_settings_service.rb @@ -22,7 +22,7 @@ module Projects # Remove remaining notification settings from source_project def remove_remaining_notification_settings - source_project.notification_settings.destroy_all + source_project.notification_settings.destroy_all # rubocop: disable DestroyAll end # Get users of current notification_settings diff --git a/app/services/projects/move_project_group_links_service.rb b/app/services/projects/move_project_group_links_service.rb index d9038030f7e..1efafdce36d 100644 --- a/app/services/projects/move_project_group_links_service.rb +++ b/app/services/projects/move_project_group_links_service.rb @@ -26,7 +26,7 @@ module Projects # Remove remaining project group links from source_project def remove_remaining_project_group_links - source_project.reload.project_group_links.destroy_all + source_project.reload.project_group_links.destroy_all # rubocop: disable DestroyAll end def group_links_in_target_project diff --git a/app/services/projects/move_project_members_service.rb b/app/services/projects/move_project_members_service.rb index bb0c0d10242..ec983582d94 100644 --- a/app/services/projects/move_project_members_service.rb +++ b/app/services/projects/move_project_members_service.rb @@ -25,7 +25,7 @@ module Projects def remove_remaining_members # Remove remaining members and authorizations from source_project - source_project.project_members.destroy_all + source_project.project_members.destroy_all # rubocop: disable DestroyAll end def project_members_in_target_project diff --git a/app/services/protected_branches/legacy_api_update_service.rb b/app/services/protected_branches/legacy_api_update_service.rb index 1f6bbe72f85..da8bf2ce02a 100644 --- a/app/services/protected_branches/legacy_api_update_service.rb +++ b/app/services/protected_branches/legacy_api_update_service.rb @@ -38,11 +38,11 @@ module ProtectedBranches def delete_redundant_access_levels unless @developers_can_merge.nil? - @protected_branch.merge_access_levels.destroy_all + @protected_branch.merge_access_levels.destroy_all # rubocop: disable DestroyAll end unless @developers_can_push.nil? - @protected_branch.push_access_levels.destroy_all + @protected_branch.push_access_levels.destroy_all # rubocop: disable DestroyAll end end end diff --git a/app/workers/remove_expired_group_links_worker.rb b/app/workers/remove_expired_group_links_worker.rb index 6b8b972a440..25128caf72f 100644 --- a/app/workers/remove_expired_group_links_worker.rb +++ b/app/workers/remove_expired_group_links_worker.rb @@ -5,6 +5,6 @@ class RemoveExpiredGroupLinksWorker include CronjobQueue def perform - ProjectGroupLink.expired.destroy_all + ProjectGroupLink.expired.destroy_all # rubocop: disable DestroyAll end end diff --git a/app/workers/remove_old_web_hook_logs_worker.rb b/app/workers/remove_old_web_hook_logs_worker.rb index 17140ac4450..0f486f8991d 100644 --- a/app/workers/remove_old_web_hook_logs_worker.rb +++ b/app/workers/remove_old_web_hook_logs_worker.rb @@ -6,7 +6,9 @@ class RemoveOldWebHookLogsWorker WEB_HOOK_LOG_LIFETIME = 2.days + # rubocop: disable DestroyAll def perform WebHookLog.destroy_all(['created_at < ?', Time.now - WEB_HOOK_LOG_LIFETIME]) end + # rubocop: enable DestroyAll end diff --git a/db/migrate/20160712171823_remove_award_emojis_with_no_user.rb b/db/migrate/20160712171823_remove_award_emojis_with_no_user.rb index 668c22bb51c..8ebf1a5234d 100644 --- a/db/migrate/20160712171823_remove_award_emojis_with_no_user.rb +++ b/db/migrate/20160712171823_remove_award_emojis_with_no_user.rb @@ -16,6 +16,6 @@ class RemoveAwardEmojisWithNoUser < ActiveRecord::Migration # disable_ddl_transaction! def up - AwardEmoji.joins('LEFT JOIN users ON users.id = user_id').where('users.id IS NULL').destroy_all + AwardEmoji.joins('LEFT JOIN users ON users.id = user_id').where('users.id IS NULL').destroy_all # rubocop: disable DestroyAll end end diff --git a/lib/gitlab/import_export/members_mapper.rb b/lib/gitlab/import_export/members_mapper.rb index ac827cbe1ca..bcbaf00e11b 100644 --- a/lib/gitlab/import_export/members_mapper.rb +++ b/lib/gitlab/import_export/members_mapper.rb @@ -45,7 +45,7 @@ module Gitlab end def ensure_default_member! - @project.project_members.destroy_all + @project.project_members.destroy_all # rubocop: disable DestroyAll ProjectMember.create!(user: @user, access_level: ProjectMember::MAINTAINER, source_id: @project.id, importing: true) end diff --git a/rubocop/cop/destroy_all.rb b/rubocop/cop/destroy_all.rb new file mode 100644 index 00000000000..38b6cb40f91 --- /dev/null +++ b/rubocop/cop/destroy_all.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # Cop that blacklists the use of `destroy_all`. + class DestroyAll < RuboCop::Cop::Cop + MSG = 'Use `delete_all` instead of `destroy_all`. ' \ + '`destroy_all` will load the rows into memory, then execute a ' \ + '`DELETE` for every individual row.' + + def_node_matcher :destroy_all?, <<~PATTERN + (send {send ivar lvar const} :destroy_all ...) + PATTERN + + def on_send(node) + return unless destroy_all?(node) + + add_offense(node, location: :expression) + end + end + end +end diff --git a/rubocop/rubocop.rb b/rubocop/rubocop.rb index a427208cdab..88c9bbf24f4 100644 --- a/rubocop/rubocop.rb +++ b/rubocop/rubocop.rb @@ -27,3 +27,4 @@ require_relative 'cop/project_path_helper' require_relative 'cop/rspec/env_assignment' require_relative 'cop/rspec/factories_in_migration_specs' require_relative 'cop/sidekiq_options_queue' +require_relative 'cop/destroy_all' diff --git a/spec/controllers/omniauth_callbacks_controller_spec.rb b/spec/controllers/omniauth_callbacks_controller_spec.rb index b23f183fec8..d377d69457f 100644 --- a/spec/controllers/omniauth_callbacks_controller_spec.rb +++ b/spec/controllers/omniauth_callbacks_controller_spec.rb @@ -95,7 +95,7 @@ describe OmniauthCallbacksController, type: :controller do end it 'allows linking the disabled provider' do - user.identities.destroy_all + user.identities.destroy_all # rubocop: disable DestroyAll sign_in(user) expect { post provider }.to change { user.reload.identities.count }.by(1) diff --git a/spec/controllers/projects/releases_controller_spec.rb b/spec/controllers/projects/releases_controller_spec.rb index fc1619acec6..20a6beb3df8 100644 --- a/spec/controllers/projects/releases_controller_spec.rb +++ b/spec/controllers/projects/releases_controller_spec.rb @@ -14,7 +14,7 @@ describe Projects::ReleasesController do describe 'GET #edit' do it 'initializes a new release' do tag_id = release.tag - project.releases.destroy_all + project.releases.destroy_all # rubocop: disable DestroyAll get :edit, namespace_id: project.namespace, project_id: project, tag_id: tag_id diff --git a/spec/lib/gitlab/background_migration/create_gpg_key_subkeys_from_gpg_keys_spec.rb b/spec/lib/gitlab/background_migration/create_gpg_key_subkeys_from_gpg_keys_spec.rb index 26d48cc8201..f92acf61682 100644 --- a/spec/lib/gitlab/background_migration/create_gpg_key_subkeys_from_gpg_keys_spec.rb +++ b/spec/lib/gitlab/background_migration/create_gpg_key_subkeys_from_gpg_keys_spec.rb @@ -5,7 +5,7 @@ describe Gitlab::BackgroundMigration::CreateGpgKeySubkeysFromGpgKeys, :migration let!(:gpg_key) { create(:gpg_key, key: GpgHelpers::User3.public_key) } before do - GpgKeySubkey.destroy_all + GpgKeySubkey.destroy_all # rubocop: disable DestroyAll end it 'generate the subkeys' do diff --git a/spec/migrations/schedule_create_gpg_key_subkeys_from_gpg_keys_spec.rb b/spec/migrations/schedule_create_gpg_key_subkeys_from_gpg_keys_spec.rb index 96bef107599..c4427910518 100644 --- a/spec/migrations/schedule_create_gpg_key_subkeys_from_gpg_keys_spec.rb +++ b/spec/migrations/schedule_create_gpg_key_subkeys_from_gpg_keys_spec.rb @@ -6,7 +6,7 @@ describe ScheduleCreateGpgKeySubkeysFromGpgKeys, :migration, :sidekiq do create(:gpg_key, id: 1, key: GpgHelpers::User1.public_key) # rubocop:disable RSpec/FactoriesInMigrationSpecs create(:gpg_key, id: 2, key: GpgHelpers::User3.public_key) # rubocop:disable RSpec/FactoriesInMigrationSpecs # Delete all subkeys so they can be recreated - GpgKeySubkey.destroy_all + GpgKeySubkey.destroy_all # rubocop: disable DestroyAll end it 'correctly schedules background migrations' do diff --git a/spec/models/fork_network_member_spec.rb b/spec/models/fork_network_member_spec.rb index 25bf596fddc..60d04562e6c 100644 --- a/spec/models/fork_network_member_spec.rb +++ b/spec/models/fork_network_member_spec.rb @@ -11,7 +11,7 @@ describe ForkNetworkMember do let(:fork_network) { fork_network_member.fork_network } it 'removes the fork network if it was the last member' do - fork_network.fork_network_members.destroy_all + fork_network.fork_network_members.destroy_all # rubocop: disable DestroyAll expect(ForkNetwork.count).to eq(0) end diff --git a/spec/models/hooks/system_hook_spec.rb b/spec/models/hooks/system_hook_spec.rb index 01129df1107..edd1cb455af 100644 --- a/spec/models/hooks/system_hook_spec.rb +++ b/spec/models/hooks/system_hook_spec.rb @@ -73,7 +73,7 @@ describe SystemHook do it "project_destroy hook" do project.add_maintainer(user) - project.project_members.destroy_all + project.project_members.destroy_all # rubocop: disable DestroyAll expect(WebMock).to have_requested(:post, system_hook.url).with( body: /user_remove_from_team/, @@ -110,7 +110,7 @@ describe SystemHook do it 'group member destroy hook' do group.add_maintainer(user) - group.group_members.destroy_all + group.group_members.destroy_all # rubocop: disable DestroyAll expect(WebMock).to have_requested(:post, system_hook.url).with( body: /user_remove_from_group/, diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 6258bfa232f..48f4e53b93e 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -1764,7 +1764,7 @@ describe MergeRequest do context 'with no discussions' do before do - merge_request.notes.destroy_all + merge_request.notes.destroy_all # rubocop: disable DestroyAll end it 'returns true' do diff --git a/spec/models/project_group_link_spec.rb b/spec/models/project_group_link_spec.rb index 1fccf92627a..5bea21427d4 100644 --- a/spec/models/project_group_link_spec.rb +++ b/spec/models/project_group_link_spec.rb @@ -41,7 +41,7 @@ describe ProjectGroupLink do project.project_group_links.create(group: group) group_users.each { |user| expect(user.authorized_projects).to include(project) } - project.project_group_links.destroy_all + project.project_group_links.destroy_all # rubocop: disable DestroyAll group_users.each { |user| expect(user.authorized_projects).not_to include(project) } end end diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb index 35951251bc5..615fea11f26 100644 --- a/spec/policies/group_policy_spec.rb +++ b/spec/policies/group_policy_spec.rb @@ -205,7 +205,7 @@ describe GroupPolicy do nested_group.add_guest(developer) nested_group.add_guest(maintainer) - group.owners.destroy_all + group.owners.destroy_all # rubocop: disable DestroyAll group.add_guest(owner) nested_group.add_owner(owner) diff --git a/spec/rubocop/cop/destroy_all_spec.rb b/spec/rubocop/cop/destroy_all_spec.rb new file mode 100644 index 00000000000..b0bc40552b3 --- /dev/null +++ b/spec/rubocop/cop/destroy_all_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper' +require 'rubocop' +require 'rubocop/rspec/support' +require_relative '../../../rubocop/cop/destroy_all' + +describe RuboCop::Cop::DestroyAll do + include CopHelper + + subject(:cop) { described_class.new } + + it 'flags the use of destroy_all with a send receiver' do + inspect_source('foo.destroy_all # rubocop: disable DestroyAll') + + expect(cop.offenses.size).to eq(1) + end + + it 'flags the use of destroy_all with a constant receiver' do + inspect_source('User.destroy_all # rubocop: disable DestroyAll') + + expect(cop.offenses.size).to eq(1) + end + + it 'flags the use of destroy_all when passing arguments' do + inspect_source('User.destroy_all([])') + + expect(cop.offenses.size).to eq(1) + end + + it 'flags the use of destroy_all with a local variable receiver' do + inspect_source(<<~RUBY) + users = User.all + users.destroy_all # rubocop: disable DestroyAll + RUBY + + expect(cop.offenses.size).to eq(1) + end + + it 'does not flag the use of delete_all' do + inspect_source('foo.delete_all') + + expect(cop.offenses).to be_empty + end +end diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb index 06fb61baf33..74bcc15f912 100644 --- a/spec/services/merge_requests/create_service_spec.rb +++ b/spec/services/merge_requests/create_service_spec.rb @@ -134,9 +134,11 @@ describe MergeRequests::CreateService do let!(:pipeline_3) { create(:ci_pipeline, project: project, ref: "other_branch", project_id: project.id) } before do + # rubocop: disable DestroyAll project.merge_requests .where(source_branch: opts[:source_branch], target_branch: opts[:target_branch]) .destroy_all + # rubocop: enable DestroyAll end it 'sets head pipeline' do diff --git a/spec/services/merge_requests/delete_non_latest_diffs_service_spec.rb b/spec/services/merge_requests/delete_non_latest_diffs_service_spec.rb index 1c632847940..6268c149fc6 100644 --- a/spec/services/merge_requests/delete_non_latest_diffs_service_spec.rb +++ b/spec/services/merge_requests/delete_non_latest_diffs_service_spec.rb @@ -46,10 +46,12 @@ describe MergeRequests::DeleteNonLatestDiffsService, :clean_gitlab_redis_shared_ end it 'schedules no removal if there is no non-latest diffs' do + # rubocop: disable DestroyAll merge_request .merge_request_diffs .where.not(id: merge_request.latest_merge_request_diff_id) .destroy_all + # rubocop: enable DestroyAll expect(DeleteDiffFilesWorker).not_to receive(:bulk_perform_in) diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb index 9a51c873b30..1746721b0d0 100644 --- a/spec/services/todo_service_spec.rb +++ b/spec/services/todo_service_spec.rb @@ -280,7 +280,7 @@ describe TodoService do end it 'does not create a todo if unassigned' do - issue.assignees.destroy_all + issue.assignees.destroy_all # rubocop: disable DestroyAll should_not_create_any_todo { service.reassigned_issue(issue, author) } end diff --git a/spec/support/shared_examples/fast_destroy_all.rb b/spec/support/shared_examples/fast_destroy_all.rb index 5448ddcfe33..a8079b6d864 100644 --- a/spec/support/shared_examples/fast_destroy_all.rb +++ b/spec/support/shared_examples/fast_destroy_all.rb @@ -4,8 +4,8 @@ shared_examples_for 'fast destroyable' do expect(external_data_counter).to be > 0 expect(subjects.count).to be > 0 - expect { subjects.first.destroy }.to raise_error('`destroy` and `destroy_all` are forbbiden. Please use `fast_destroy_all`') - expect { subjects.destroy_all }.to raise_error('`destroy` and `destroy_all` are forbbiden. Please use `fast_destroy_all`') + expect { subjects.first.destroy }.to raise_error('`destroy` and `destroy_all` are forbidden. Please use `fast_destroy_all`') + expect { subjects.destroy_all }.to raise_error('`destroy` and `destroy_all` are forbidden. Please use `fast_destroy_all`') # rubocop: disable DestroyAll expect(subjects.count).to be > 0 expect(external_data_counter).to be > 0 diff --git a/spec/workers/repository_check/single_repository_worker_spec.rb b/spec/workers/repository_check/single_repository_worker_spec.rb index 22fc64c1536..f11875cffd1 100644 --- a/spec/workers/repository_check/single_repository_worker_spec.rb +++ b/spec/workers/repository_check/single_repository_worker_spec.rb @@ -6,7 +6,7 @@ describe RepositoryCheck::SingleRepositoryWorker do it 'skips when the project has no push events' do project = create(:project, :repository, :wiki_disabled) - project.events.destroy_all + project.events.destroy_all # rubocop: disable DestroyAll break_project(project) expect(worker).not_to receive(:git_fsck) |