discourse/migrations/lib/converters.rb
Gerhard Schlager 89f26da39d
MT: Switch to nested module style across migrations/ (#38564)
Ruby's compact module syntax (`module
Migrations::Database::Schema::DSL`) breaks lexical constant lookup —
`Module.nesting` only includes the innermost constant, so every
cross-module reference must be fully qualified. In practice this means
writing `Migrations::Database::Schema::Helpers` even when you're already
inside `Migrations::Database::Schema`.

Nested module definitions restore the full nesting chain, which brings
several practical benefits:

- **Less verbose code**: references like `Schema::Helpers`,
`Database::IntermediateDB`, or `Converters::Base::ProgressStep` work
without repeating the full path from root
- **Easier to write new code**: contributors don't need to remember
which prefixes are required — if you're inside the namespace, short
names just work
- **Fewer aliasing workarounds**: removes the need for constants like
`MappingType = Migrations::Importer::MappingType` that existed solely to
shorten references
- **Standard Ruby style**: consistent with how most Ruby projects and
gems structure their namespaces

The diff is large but mechanical — no logic changes, just module
wrapping and shortening references that the nesting now resolves.
Generated code (intermediate_db models/enums) keeps fully qualified
references like `Migrations::Database.format_*` since it must work
regardless of the configured output namespace.

- Convert 138 lib files from compact to nested module definitions
- Remove now-redundant fully qualified prefixes and aliases
- Update model and enum writers to generate nested modules with correct
indentation
- Regenerate all intermediate_db models and enums
2026-03-19 18:15:19 +01:00

48 lines
1.4 KiB
Ruby

# frozen_string_literal: true
module Migrations
module Converters
def self.all
@all_converters ||=
begin
base_path = File.join(Migrations.root_path, "lib", "converters", "base")
core_paths = Dir[File.join(Migrations.root_path, "lib", "converters", "*")]
private_paths = Dir[File.join(Migrations.root_path, "private", "converters", "*")]
all_paths = core_paths - [base_path] + private_paths
all_paths.each_with_object({}) do |path, hash|
next unless File.directory?(path)
name = File.basename(path).downcase
existing_path = hash[name]
raise <<~MSG if existing_path
Duplicate converter name found: #{name}
* #{existing_path}
* #{path}
MSG
hash[name] = path
end
end
end
def self.names
self.all.keys.sort
end
def self.path_of(converter_name)
converter_name = converter_name.downcase
path = self.all[converter_name]
raise "Could not find a converter named '#{converter_name}'" unless path
path
end
def self.default_settings_path(converter_name)
local_settings_path = File.join(path_of(converter_name), "settings.local.yml")
return local_settings_path if File.exist?(local_settings_path)
File.join(path_of(converter_name), "settings.yml")
end
end
end