From be1660741b651973dc5f8e8ef348a0c1af6e0483 Mon Sep 17 00:00:00 2001 From: Joe Woodward <jwoodward@gitlab.com> Date: Fri, 20 Dec 2024 17:44:26 +0000 Subject: [PATCH] Match namespaced factories in Migration/EnsureFactoryForTable Cop Before this change we only matched tables against their file name e.g. ```ruby create_table :projects_branch_rules_squash_options do ``` Would require a factory stored in: `spec/factories/projects_branch_rules_squash_options.rb` However, we often use namespacing to retain some structure within the codebase. This change allows us to specify a factory in: `spec/factories/projects/branch_rules/squash_options.rb` --- .../migration/ensure_factory_for_table.yml | 14 ------ ...40515022318_create_duo_workflows_tables.rb | 2 +- ...eate_dependency_list_export_parts_table.rb | 2 - ...134250_create_p_ci_build_trace_metadata.rb | 2 - ..._access_instance_microsoft_applications.rb | 3 -- ..._instance_microsoft_graph_access_tokens.rb | 3 -- ...3210_create_instance_integrations_table.rb | 2 +- ...29205910_create_ci_job_artifact_reports.rb | 2 +- ..._create_packages_conan_recipe_revisions.rb | 2 +- ...reate_packages_conan_package_references.rb | 2 +- ...2920_create_ci_job_token_authorizations.rb | 2 +- ...tem_access_group_microsoft_applications.rb | 2 +- ...ess_group_microsoft_graph_access_tokens.rb | 2 +- .../cop/migration/ensure_factory_for_table.rb | 11 +++-- .../ensure_factory_for_table_spec.rb | 47 +++++++++++++++---- 15 files changed, 53 insertions(+), 45 deletions(-) diff --git a/.rubocop_todo/migration/ensure_factory_for_table.yml b/.rubocop_todo/migration/ensure_factory_for_table.yml index 762a2b1203585..10fb9c293dee3 100644 --- a/.rubocop_todo/migration/ensure_factory_for_table.yml +++ b/.rubocop_todo/migration/ensure_factory_for_table.yml @@ -5,26 +5,16 @@ Migration/EnsureFactoryForTable: - 'db/migrate/20230926092944_add_approval_group_rules_groups.rb' - 'db/migrate/20230926093004_add_approval_group_rules_users.rb' - 'db/migrate/20230926093025_add_approval_group_rules_protected_branches.rb' - - 'db/migrate/20231017095738_create_activity_pub_releases_subscriptions.rb' - - 'db/migrate/20231017134349_create_ml_model_metadata.rb' - 'db/migrate/20231020095624_create_audit_events_streaming_http_group_namespace_filters.rb' - - 'db/migrate/20231025123238_create_compliance_framework_security_policies.rb' - 'db/migrate/20231031164724_create_sbom_occurrences_vulnerabilities.rb' - - 'db/migrate/20231102142553_add_zoekt_nodes.rb' - - 'db/migrate/20231107140642_create_audit_events_instance_amazon_s3_configurations.rb' - 'db/migrate/20231110044738_create_abuse_report_assignees_table.rb' - 'db/migrate/20231115064007_create_audit_events_streaming_http_instance_namespace_filters.rb' - 'db/migrate/20231124191759_add_catalog_resource_sync_events_table.rb' - 'db/migrate/20231207150738_add_work_item_dates_sources.rb' - - 'db/migrate/20231215192706_create_ml_model_version_metadata.rb' - 'db/migrate/20231220113459_add_work_item_color.rb' - - 'db/migrate/20231221033539_create_sbom_source_packages_table.rb' - - 'db/migrate/20231221113948_create_cloud_connector_access.rb' - 'db/migrate/20240108123023_create_ai_agents_table.rb' - 'db/migrate/20240108123115_create_ai_agent_versions_table.rb' - 'db/migrate/20240112124030_create_audit_events_group_external_streaming_destinations.rb' - - 'db/migrate/20240115185037_create_packages_terraform_module_metadata.rb' - - 'db/migrate/20240122165824_create_ci_job_token_group_scope_links.rb' - 'db/migrate/20240130162148_create_audit_events_instance_external_streaming_destinations.rb' - 'db/migrate/20240131052824_create_catalog_verified_namespaces.rb' - 'db/migrate/20240201112236_create_group_saved_replies_table.rb' @@ -34,7 +24,3 @@ Migration/EnsureFactoryForTable: - 'db/migrate/20240304184128_create_ci_build_names_table.rb' - 'db/migrate/20240306121653_create_relation_import_tracker.rb' - 'db/migrate/20240404192955_create_early_access_program_tracking_events.rb' - - 'db/migrate/20240419082037_create_ai_self_hosted_models.rb' - - 'db/migrate/20240423064716_create_ci_build_execution_config.rb' - - 'db/migrate/20240430110033_create_ai_feature_settings.rb' - - 'db/migrate/20241127092714_create_container_registry_protection_tag_rules.rb' diff --git a/db/migrate/20240515022318_create_duo_workflows_tables.rb b/db/migrate/20240515022318_create_duo_workflows_tables.rb index ac1ce36bb1763..ba00d8e939880 100644 --- a/db/migrate/20240515022318_create_duo_workflows_tables.rb +++ b/db/migrate/20240515022318_create_duo_workflows_tables.rb @@ -4,7 +4,7 @@ class CreateDuoWorkflowsTables < Gitlab::Database::Migration[2.2] milestone '17.2' def change - create_table :duo_workflows_workflows do |t| # rubocop:disable Migration/EnsureFactoryForTable -- https://gitlab.com/gitlab-org/gitlab/-/issues/468630 + create_table :duo_workflows_workflows do |t| # rubocop:disable Migration/EnsureFactoryForTable, Lint/RedundantCopDisableDirective -- https://gitlab.com/gitlab-org/gitlab/-/issues/468630 t.bigint :user_id, null: false, index: true t.bigint :project_id, null: false, index: true diff --git a/db/migrate/20240626125526_create_dependency_list_export_parts_table.rb b/db/migrate/20240626125526_create_dependency_list_export_parts_table.rb index 2f7f2ce54bc74..20851dfe73c7a 100644 --- a/db/migrate/20240626125526_create_dependency_list_export_parts_table.rb +++ b/db/migrate/20240626125526_create_dependency_list_export_parts_table.rb @@ -3,7 +3,6 @@ class CreateDependencyListExportPartsTable < Gitlab::Database::Migration[2.2] milestone '17.2' - # rubocop:disable Migration/EnsureFactoryForTable -- False Positive def change create_table :dependency_list_export_parts do |t| t.references :dependency_list_export, foreign_key: { on_delete: :cascade }, null: false, index: true @@ -15,5 +14,4 @@ def change t.text :file, limit: 255 end end - # rubocop:enable Migration/EnsureFactoryForTable end diff --git a/db/migrate/20240809134250_create_p_ci_build_trace_metadata.rb b/db/migrate/20240809134250_create_p_ci_build_trace_metadata.rb index 8224679399378..36c8bde3310bd 100644 --- a/db/migrate/20240809134250_create_p_ci_build_trace_metadata.rb +++ b/db/migrate/20240809134250_create_p_ci_build_trace_metadata.rb @@ -3,7 +3,6 @@ class CreatePCiBuildTraceMetadata < Gitlab::Database::Migration[2.2] milestone '17.4' - # rubocop:disable Migration/EnsureFactoryForTable -- No factory needed def change create_table(:p_ci_build_trace_metadata, primary_key: [:build_id, :partition_id], options: 'PARTITION BY LIST (partition_id)', if_not_exists: true) do |t| @@ -19,5 +18,4 @@ def change t.index :trace_artifact_id end end - # rubocop:enable Migration/EnsureFactoryForTable -- No factory needed end diff --git a/db/migrate/20240829143538_create_system_access_instance_microsoft_applications.rb b/db/migrate/20240829143538_create_system_access_instance_microsoft_applications.rb index 6c24f7fa617ad..0e5e84706f606 100644 --- a/db/migrate/20240829143538_create_system_access_instance_microsoft_applications.rb +++ b/db/migrate/20240829143538_create_system_access_instance_microsoft_applications.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -# rubocop:disable Migration/EnsureFactoryForTable -- False positive class CreateSystemAccessInstanceMicrosoftApplications < Gitlab::Database::Migration[2.2] milestone '17.5' @@ -17,5 +16,3 @@ def change end end end - -# rubocop:enable Migration/EnsureFactoryForTable diff --git a/db/migrate/20240829143654_create_system_access_instance_microsoft_graph_access_tokens.rb b/db/migrate/20240829143654_create_system_access_instance_microsoft_graph_access_tokens.rb index 2a42f2472f077..df804e8dc0b3b 100644 --- a/db/migrate/20240829143654_create_system_access_instance_microsoft_graph_access_tokens.rb +++ b/db/migrate/20240829143654_create_system_access_instance_microsoft_graph_access_tokens.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -# rubocop:disable Migration/EnsureFactoryForTable -- False positive class CreateSystemAccessInstanceMicrosoftGraphAccessTokens < Gitlab::Database::Migration[2.2] milestone '17.5' @@ -16,5 +15,3 @@ def change end end end - -# rubocop:enable Migration/EnsureFactoryForTable diff --git a/db/migrate/20240829163210_create_instance_integrations_table.rb b/db/migrate/20240829163210_create_instance_integrations_table.rb index 560b18185da1e..15cfbc57927ad 100644 --- a/db/migrate/20240829163210_create_instance_integrations_table.rb +++ b/db/migrate/20240829163210_create_instance_integrations_table.rb @@ -4,7 +4,7 @@ class CreateInstanceIntegrationsTable < Gitlab::Database::Migration[2.2] milestone '17.4' def up - create_table :instance_integrations, id: :bigserial do |t| # rubocop:disable Migration/EnsureFactoryForTable -- https://gitlab.com/gitlab-org/gitlab/-/issues/468630 + create_table :instance_integrations, id: :bigserial do |t| t.timestamps_with_timezone null: false t.integer :comment_detail t.boolean :active, default: false, null: false diff --git a/db/migrate/20240829205910_create_ci_job_artifact_reports.rb b/db/migrate/20240829205910_create_ci_job_artifact_reports.rb index 1430653f38cb3..394907cd18bc8 100644 --- a/db/migrate/20240829205910_create_ci_job_artifact_reports.rb +++ b/db/migrate/20240829205910_create_ci_job_artifact_reports.rb @@ -5,7 +5,7 @@ class CreateCiJobArtifactReports < Gitlab::Database::Migration[2.2] disable_ddl_transaction! def up - create_table(:p_ci_job_artifact_reports, # rubocop:disable Migration/EnsureFactoryForTable -- Factory exists + create_table(:p_ci_job_artifact_reports, primary_key: [:job_artifact_id, :partition_id], options: 'PARTITION BY LIST (partition_id)', if_not_exists: true) do |t| t.bigint :job_artifact_id, null: false diff --git a/db/migrate/20240902100524_create_packages_conan_recipe_revisions.rb b/db/migrate/20240902100524_create_packages_conan_recipe_revisions.rb index f75a28679407c..d6758775a87e8 100644 --- a/db/migrate/20240902100524_create_packages_conan_recipe_revisions.rb +++ b/db/migrate/20240902100524_create_packages_conan_recipe_revisions.rb @@ -6,7 +6,7 @@ class CreatePackagesConanRecipeRevisions < Gitlab::Database::Migration[2.2] INDEX_PACKAGE_ID_REVISION = 'idx_on_packages_conan_recipe_revisions_package_id_revision' def up - create_table :packages_conan_recipe_revisions do |t| # rubocop:disable Migration/EnsureFactoryForTable -- https://gitlab.com/gitlab-org/gitlab/-/issues/468630 + create_table :packages_conan_recipe_revisions do |t| t.bigint :package_id, null: false t.bigint :project_id, null: false t.timestamps_with_timezone null: false diff --git a/db/migrate/20240906134338_create_packages_conan_package_references.rb b/db/migrate/20240906134338_create_packages_conan_package_references.rb index ea90c4c5c0c60..6a29b7f7c3e61 100644 --- a/db/migrate/20240906134338_create_packages_conan_package_references.rb +++ b/db/migrate/20240906134338_create_packages_conan_package_references.rb @@ -7,7 +7,7 @@ class CreatePackagesConanPackageReferences < Gitlab::Database::Migration[2.2] CONSTRAINT_NAME = 'chk_conan_references_info_length' def up - create_table :packages_conan_package_references do |t| # rubocop:disable Migration/EnsureFactoryForTable -- https://gitlab.com/gitlab-org/gitlab/-/issues/468630 + create_table :packages_conan_package_references do |t| t.bigint :package_id, null: false t.bigint :project_id, null: false t.bigint :recipe_revision_id diff --git a/db/migrate/20240910132920_create_ci_job_token_authorizations.rb b/db/migrate/20240910132920_create_ci_job_token_authorizations.rb index e4709ebc2223e..4e83f4340957d 100644 --- a/db/migrate/20240910132920_create_ci_job_token_authorizations.rb +++ b/db/migrate/20240910132920_create_ci_job_token_authorizations.rb @@ -6,7 +6,7 @@ class CreateCiJobTokenAuthorizations < Gitlab::Database::Migration[2.2] INDEX_NAME = 'idx_ci_job_token_authorizations_on_accessed_and_origin_project' def change - create_table(:ci_job_token_authorizations, if_not_exists: true) do |t| # rubocop:disable Migration/EnsureFactoryForTable -- factory at ci/job_token/authorizations.rb + create_table(:ci_job_token_authorizations, if_not_exists: true) do |t| t.bigint :accessed_project_id, null: false t.bigint :origin_project_id, null: false, index: true t.datetime_with_timezone :last_authorized_at, null: false diff --git a/db/migrate/20241106114853_create_system_access_group_microsoft_applications.rb b/db/migrate/20241106114853_create_system_access_group_microsoft_applications.rb index d8f0fea8f43ed..76eaa21e96f24 100644 --- a/db/migrate/20241106114853_create_system_access_group_microsoft_applications.rb +++ b/db/migrate/20241106114853_create_system_access_group_microsoft_applications.rb @@ -5,7 +5,7 @@ class CreateSystemAccessGroupMicrosoftApplications < Gitlab::Database::Migration milestone '17.7' def change - create_table :system_access_group_microsoft_applications do |t| # rubocop:disable Migration/EnsureFactoryForTable -- False positive, factory name is prefixed with system_access + create_table :system_access_group_microsoft_applications do |t| t.timestamps_with_timezone null: false t.references :group, foreign_key: { to_table: :namespaces, on_delete: :cascade }, null: false t.bigint :temp_source_id, index: { unique: true, name: 'index_group_microsoft_applications_on_temp_source_id' }, diff --git a/db/migrate/20241106115015_create_system_access_group_microsoft_graph_access_tokens.rb b/db/migrate/20241106115015_create_system_access_group_microsoft_graph_access_tokens.rb index ab715dd93c496..a0898f69740d7 100644 --- a/db/migrate/20241106115015_create_system_access_group_microsoft_graph_access_tokens.rb +++ b/db/migrate/20241106115015_create_system_access_group_microsoft_graph_access_tokens.rb @@ -5,7 +5,7 @@ class CreateSystemAccessGroupMicrosoftGraphAccessTokens < Gitlab::Database::Migr milestone '17.7' def change - create_table :system_access_group_microsoft_graph_access_tokens do |t| # rubocop:disable Migration/EnsureFactoryForTable -- False positive, factory name is prefixed with system_access + create_table :system_access_group_microsoft_graph_access_tokens do |t| t.timestamps_with_timezone null: false t.references :system_access_group_microsoft_application, index: { name: 'unique_index_group_ms_access_tokens_on_ms_app_id', unique: true } diff --git a/rubocop/cop/migration/ensure_factory_for_table.rb b/rubocop/cop/migration/ensure_factory_for_table.rb index e453605d0606f..1636671bf9718 100644 --- a/rubocop/cop/migration/ensure_factory_for_table.rb +++ b/rubocop/cop/migration/ensure_factory_for_table.rb @@ -47,7 +47,8 @@ def on_send(node) return if !ee? && disabled_comment_absent? table_definition(node) do |table_name_node, table_name| - unless factory?(table_name.to_s) + # Partioned tables are prefix with `p_`. + unless factory?(table_name.to_s.delete_prefix('p_')) msg = format(MSG, name: table_name) add_offense(table_name_node, message: msg) end @@ -57,13 +58,13 @@ def on_send(node) private def factory?(table_name) - end_with = "/#{table_name}.rb" - - self.class.factories.any? { |path| path.end_with?(end_with) } + self.class.factories.any? { |name| name.end_with?(table_name) } end def self.factories - @factories ||= Dir.glob("{,ee/,jh/}spec/factories/**/*.rb") + @factories ||= Dir.glob("{,ee/,jh/}spec/factories/**/*.rb").map do |factory| + factory.gsub(%r{^(ee/|jh/|)spec/factories/}, '').delete_suffix('.rb').tr('/', '_') + end end def disabled_comment_absent? diff --git a/spec/rubocop/cop/migration/ensure_factory_for_table_spec.rb b/spec/rubocop/cop/migration/ensure_factory_for_table_spec.rb index e10864dc1d81b..208b123b7f713 100644 --- a/spec/rubocop/cop/migration/ensure_factory_for_table_spec.rb +++ b/spec/rubocop/cop/migration/ensure_factory_for_table_spec.rb @@ -83,22 +83,53 @@ end context 'with matching factories' do - let(:factories) { ['spec/factories/users.rb'] } + context 'with regular table' do + let(:factories) { ['users'] } - it 'does not register an offense when a table has a corresponding factory' do - expect_no_offenses(<<~RUBY) - create_table :users do |t| - t.string :name - t.timestamps + it 'does not register an offense when a table has a corresponding factory' do + expect_no_offenses(<<~RUBY) + create_table :users do |t| + t.string :name + t.timestamps + end + RUBY + end + end + + context 'with partitioned table' do + let(:factories) { ['users'] } + + it 'does not register an offense when a table has a corresponding factory' do + expect_no_offenses(<<~RUBY) + create_table :p_users do |t| + t.string :name + t.timestamps + end + RUBY end - RUBY end end end describe '.factories' do + let(:table_names) { %w[unnested_ce nested_ce_factory unnested_ee nested_ee_factory unnested_jh nested_jh_factory] } + let(:factories) do + %w[ + spec/factories/unnested_ce.rb + spec/factories/nested/ce/factory.rb + ee/spec/factories/unnested_ee.rb + ee/spec/factories/nested/ee_factory.rb + jh/spec/factories/unnested_jh.rb + jh/spec/factories/nested_jh/factory.rb + ] + end + + before do + allow(Dir).to receive(:glob).and_return(factories) + end + subject { described_class.factories } - it { is_expected.not_to be_empty } + it { is_expected.to eq(table_names) } end end -- GitLab