mirror of
https://github.com/discourse/discourse.git
synced 2024-11-25 09:42:07 +08:00
DEV: Custom generator for move setting from tl to groups (#24912)
Ability to automatically generate migration when site setting is changed from trust level to groups. Example usage: rails generate site_setting_move_to_groups_migration min_trust_to_create_topic create_topic_allowed_groups
This commit is contained in:
parent
dce5e811ef
commit
4c8bc34475
|
@ -0,0 +1,8 @@
|
||||||
|
Description:
|
||||||
|
Generates migration to move data from trust level based site setting to group based site setting. It only works when moving from TrustLevelSetting or TrustLevelAndStaffSetting.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
bin/rails generate site_setting_move_to_groups_migration min_trust_to_create_topic create_topic_allowed_groups
|
||||||
|
|
||||||
|
This will create:
|
||||||
|
db/migrate/20231206041353_fill_create_topic_allowed_groups_based_on_deprecated_settings.rb
|
|
@ -0,0 +1,111 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class SiteSettingMoveToGroupsMigrationGenerator < Rails::Generators::Base
|
||||||
|
include SiteSettingExtension
|
||||||
|
|
||||||
|
argument :old_name, type: :string, banner: "old setting name", required: true
|
||||||
|
argument :new_name, type: :string, banner: "new setting name", required: true
|
||||||
|
|
||||||
|
def create_migration_file
|
||||||
|
migration_version = ActiveRecord::Migration.next_migration_number(0)
|
||||||
|
file_path = "db/migrate/#{migration_version}_fill_#{new_name}_based_on_deprecated_setting.rb"
|
||||||
|
class_name = "Fill#{new_name.classify}BasedOnDeprecatedSetting"
|
||||||
|
|
||||||
|
validate_setting_name!(old_name)
|
||||||
|
validate_setting_name!(new_name)
|
||||||
|
validate_setting_type!(old_name)
|
||||||
|
|
||||||
|
create_file file_path, <<~MIGRATION_FILE if setting_type(old_name) == "TrustLevelSetting"
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class #{class_name} < ActiveRecord::Migration[7.0]
|
||||||
|
def up
|
||||||
|
old_setting_trust_level =
|
||||||
|
DB.query_single(
|
||||||
|
"SELECT value FROM site_settings WHERE name = '#{old_name}' LIMIT 1",
|
||||||
|
).first
|
||||||
|
|
||||||
|
if old_setting_trust_level.present?
|
||||||
|
allowed_groups = "1\#\{old_setting_trust_level\}"
|
||||||
|
|
||||||
|
DB.exec(
|
||||||
|
"INSERT INTO site_settings(name, value, data_type, created_at, updated_at)
|
||||||
|
VALUES('#{new_name}', :setting, '20', NOW(), NOW())",
|
||||||
|
setting: allowed_groups,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
raise ActiveRecord::IrreversibleMigration
|
||||||
|
end
|
||||||
|
end
|
||||||
|
MIGRATION_FILE
|
||||||
|
if setting_type(old_name) == "TrustLevelAndStaffSetting"
|
||||||
|
create_file file_path, <<~MIGRATION_FILE
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class #{class_name} < ActiveRecord::Migration[7.0]
|
||||||
|
def up
|
||||||
|
old_setting_trust_level =
|
||||||
|
DB.query_single(
|
||||||
|
"SELECT value FROM site_settings WHERE name = '#{old_name}' LIMIT 1",
|
||||||
|
).first
|
||||||
|
|
||||||
|
if old_setting_trust_level.present?
|
||||||
|
allowed_groups =
|
||||||
|
case old_setting_trust_level
|
||||||
|
when "admin"
|
||||||
|
"1"
|
||||||
|
when "staff"
|
||||||
|
"3"
|
||||||
|
when "0"
|
||||||
|
"10"
|
||||||
|
when "1"
|
||||||
|
"11"
|
||||||
|
when "2"
|
||||||
|
"12"
|
||||||
|
when "3"
|
||||||
|
"13"
|
||||||
|
when "4"
|
||||||
|
"14"
|
||||||
|
end
|
||||||
|
|
||||||
|
DB.exec(
|
||||||
|
"INSERT INTO site_settings(name, value, data_type, created_at, updated_at)
|
||||||
|
VALUES('#{new_name}', :setting, '20', NOW(), NOW())",
|
||||||
|
setting: allowed_groups,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
raise ActiveRecord::IrreversibleMigration
|
||||||
|
end
|
||||||
|
end
|
||||||
|
MIGRATION_FILE
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def validate_setting_name!(name)
|
||||||
|
if !SiteSetting.respond_to?(name)
|
||||||
|
say "Site setting with #{name} does not exist"
|
||||||
|
raise ArgumentError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def setting_type(name)
|
||||||
|
@site_settings ||= load_settings(File.join(Rails.root, "config", "site_settings.yml"))
|
||||||
|
subgroup = @site_settings.values.find { |row| row.keys.include?(name) }
|
||||||
|
subgroup[name][:enum]
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate_setting_type!(name)
|
||||||
|
if !%w[TrustLevelSetting TrustLevelAndStaffSetting].include?(setting_type(name))
|
||||||
|
say "Site setting with #{name} must be TrustLevelSetting"
|
||||||
|
raise ArgumentError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -5,8 +5,8 @@ class SiteSettingRenameMigrationGenerator < Rails::Generators::Base
|
||||||
argument :new_name, type: :string, banner: "new setting name", required: true
|
argument :new_name, type: :string, banner: "new setting name", required: true
|
||||||
|
|
||||||
def create_migration_file
|
def create_migration_file
|
||||||
timestamp = Time.zone.now.to_s.tr("^0-9", "")[0..13]
|
migration_version = ActiveRecord::Migration.next_migration_number(0)
|
||||||
file_path = "db/migrate/#{timestamp}_rename_#{old_name}_setting.rb"
|
file_path = "db/migrate/#{migration_version}_rename_#{old_name}_setting.rb"
|
||||||
class_name = "Rename#{old_name.classify}Setting"
|
class_name = "Rename#{old_name.classify}Setting"
|
||||||
|
|
||||||
validate_setting_name!(old_name)
|
validate_setting_name!(old_name)
|
||||||
|
@ -30,9 +30,7 @@ class SiteSettingRenameMigrationGenerator < Rails::Generators::Base
|
||||||
private
|
private
|
||||||
|
|
||||||
def validate_setting_name!(name)
|
def validate_setting_name!(name)
|
||||||
begin
|
if !SiteSetting.respond_to?(name)
|
||||||
SiteSetting.send(name)
|
|
||||||
rescue NoMethodError
|
|
||||||
say "Site setting with #{name} does not exist"
|
say "Site setting with #{name} does not exist"
|
||||||
raise ArgumentError
|
raise ArgumentError
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "rails_helper"
|
||||||
|
require "rails/generators"
|
||||||
|
require "generators/site_setting_move_to_groups_migration/site_setting_move_to_groups_migration_generator"
|
||||||
|
|
||||||
|
RSpec.describe SiteSettingMoveToGroupsMigrationGenerator, type: :generator do
|
||||||
|
it "generates the correct migration for TrustLevelSetting" do
|
||||||
|
freeze_time DateTime.parse("2010-01-01 12:00")
|
||||||
|
described_class
|
||||||
|
.any_instance
|
||||||
|
.expects(:load_settings)
|
||||||
|
.returns({ branding: { "site_description" => { enum: "TrustLevelSetting" } } })
|
||||||
|
|
||||||
|
described_class.start(%w[site_description contact_email], destination_root: "#{Rails.root}/tmp")
|
||||||
|
file_path =
|
||||||
|
"#{Rails.root}/tmp/db/migrate/20100101120000_fill_contact_email_based_on_deprecated_setting.rb"
|
||||||
|
|
||||||
|
expected_content = <<~EXPECTED_CONTENT
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class FillContactEmailBasedOnDeprecatedSetting < ActiveRecord::Migration[7.0]
|
||||||
|
def up
|
||||||
|
old_setting_trust_level =
|
||||||
|
DB.query_single(
|
||||||
|
"SELECT value FROM site_settings WHERE name = 'site_description' LIMIT 1",
|
||||||
|
).first
|
||||||
|
|
||||||
|
if old_setting_trust_level.present?
|
||||||
|
allowed_groups = "1\#\{old_setting_trust_level\}"
|
||||||
|
|
||||||
|
DB.exec(
|
||||||
|
"INSERT INTO site_settings(name, value, data_type, created_at, updated_at)
|
||||||
|
VALUES('contact_email', :setting, '20', NOW(), NOW())",
|
||||||
|
setting: allowed_groups,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
raise ActiveRecord::IrreversibleMigration
|
||||||
|
end
|
||||||
|
end
|
||||||
|
EXPECTED_CONTENT
|
||||||
|
|
||||||
|
expect(File.read(file_path)).to eq(expected_content)
|
||||||
|
File.delete(file_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "generates the correct migration for TrustLevelAndStaffSetting" do
|
||||||
|
freeze_time DateTime.parse("2010-01-01 12:00")
|
||||||
|
described_class
|
||||||
|
.any_instance
|
||||||
|
.expects(:load_settings)
|
||||||
|
.returns({ branding: { "title" => { enum: "TrustLevelAndStaffSetting" } } })
|
||||||
|
|
||||||
|
described_class.start(%w[title contact_email], destination_root: "#{Rails.root}/tmp")
|
||||||
|
file_path =
|
||||||
|
"#{Rails.root}/tmp/db/migrate/20100101120000_fill_contact_email_based_on_deprecated_setting.rb"
|
||||||
|
|
||||||
|
expected_content = <<~EXPECTED_CONTENT
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class FillContactEmailBasedOnDeprecatedSetting < ActiveRecord::Migration[7.0]
|
||||||
|
def up
|
||||||
|
old_setting_trust_level =
|
||||||
|
DB.query_single(
|
||||||
|
"SELECT value FROM site_settings WHERE name = 'title' LIMIT 1",
|
||||||
|
).first
|
||||||
|
|
||||||
|
if old_setting_trust_level.present?
|
||||||
|
allowed_groups =
|
||||||
|
case old_setting_trust_level
|
||||||
|
when "admin"
|
||||||
|
"1"
|
||||||
|
when "staff"
|
||||||
|
"3"
|
||||||
|
when "0"
|
||||||
|
"10"
|
||||||
|
when "1"
|
||||||
|
"11"
|
||||||
|
when "2"
|
||||||
|
"12"
|
||||||
|
when "3"
|
||||||
|
"13"
|
||||||
|
when "4"
|
||||||
|
"14"
|
||||||
|
end
|
||||||
|
|
||||||
|
DB.exec(
|
||||||
|
"INSERT INTO site_settings(name, value, data_type, created_at, updated_at)
|
||||||
|
VALUES('contact_email', :setting, '20', NOW(), NOW())",
|
||||||
|
setting: allowed_groups,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
raise ActiveRecord::IrreversibleMigration
|
||||||
|
end
|
||||||
|
end
|
||||||
|
EXPECTED_CONTENT
|
||||||
|
|
||||||
|
expect(File.read(file_path)).to eq(expected_content)
|
||||||
|
File.delete(file_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises an error when old name is incorrect" do
|
||||||
|
expect { described_class.start(%w[wrong_name contact_email]) }.to raise_error(ArgumentError)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises an error when new name is incorrect" do
|
||||||
|
expect { described_class.start(%w[site_description wrong_name]) }.to raise_error(ArgumentError)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises an error when old setting is incorrect type" do
|
||||||
|
described_class
|
||||||
|
.any_instance
|
||||||
|
.expects(:load_settings)
|
||||||
|
.returns({ branding: { "site_description" => { enum: "EmojiSetSiteSetting" } } })
|
||||||
|
expect { described_class.start(%w[site_description contact_email]) }.to raise_error(
|
||||||
|
ArgumentError,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user