Skip to content

Settings conversion cannot be skipped via configuration - blocks entire conversion #21

@web-engineer

Description

@web-engineer

Description

Summary

The redmine_reformat plugin fails when converting Textile→Markdown because Settings (like welcome_text) are processed separately from other items and cannot be excluded via the converters_json configuration. This blocks the entire conversion process even when Settings are empty or deleted from the database.

Environment

  • Redmine version: 6.1 (official Docker image)
  • Plugin version: Latest from master (commit 18d0061)
  • Ruby version: 3.1.x
  • Database: PostgreSQL 14

Problem

Settings are hard-coded to migrate first via migrate_settings() (before migrate_objects()) and the configurable converter matching via items filter only applies to objects (Issues, Wiki, etc.), not Settings.

Code reference:

# lib/redmine_reformat/convert_redmine.rb line ~130
def do_migrate
  @from_formatting = Setting.text_formatting
  @to_formatting = @exn.to_formatting || @from_formatting
  @exn.start
  migrate_settings if @exn.master?  # <-- Always runs, no way to skip
  migrate_objects                    # <-- Items filter applies here
  migrate_wiki_versions
  ...
end

Reproduction Steps

  1. Install redmine_reformat plugin
  2. Set Setting.text_formatting = 'textile'
  3. Ensure welcome_text Setting exists (even if empty/blank)
  4. Attempt to skip Settings conversion:
# Attempt 1: Using items filter to exclude Settings
convcfg='[{
  "items": ["Setting"],
  "from_formatting": "textile",
  "to_formatting": "common_mark",
  "converters": null
}]'
rake reformat:convert to_formatting=common_mark converters_json="$convcfg"
# Result: FAILED - Settings still processed, not matched by items filter
# Attempt 2: Try CONVERTERS_JSON to exclude Setting class
rake reformat:convert SOURCE_FORMATTING=textile TARGET_FORMATTING=common_mark \
  CONVERTERS_JSON='{"Setting":[]}'
# Result: FAILED - Environment variable not parsed (shows "use default converters")
# Attempt 3: Delete problematic Setting from database
rails runner "Setting.where(name: 'welcome_text').destroy_all"
rake reformat:convert SOURCE_FORMATTING=textile TARGET_FORMATTING=common_mark
# Result: FAILED - Plugin still fails on welcome_text (caching/transaction issue)

Error output:

Settings
rake aborted!
No converter found for Setting#welcome_text
/usr/src/redmine/plugins/redmine_reformat/lib/redmine_reformat/converters/configured_converters.rb:14:in `convert'
/usr/src/redmine/plugins/redmine_reformat/lib/redmine_reformat/convert_redmine.rb:243:in `convert'
/usr/src/redmine/plugins/redmine_reformat/lib/redmine_reformat/convert_redmine.rb:158:in `migrate_setting'

Root Cause Analysis

  1. Settings processed separately: migrate_settings() is called independently from migrate_objects()
  2. Hard-coded Settings list: SETTINGS_TO_MIGRATE = %w(welcome_text emails_footer emails_header) at line ~99
  3. No filter mechanism: Settings don't have a Spec object like other items, so they bypass the configurable matching system
  4. Converter lookup happens regardless: Even empty/nil Settings trigger converter lookup in migrate_setting()

Expected Behavior

One of the following solutions would work:

Option 1: Respect items filter

def migrate_settings
  return unless @exn.converter_matches_item?('Setting')  # Add this check
  STDERR.puts "Settings"
  SETTINGS_TO_MIGRATE.each do |setting|
    migrate_setting setting
  end
end

Option 2: Skip nil/empty Settings

def migrate_setting(name)
  ctx = Context.new(...)
  textile = Setting.send(name)
  return if textile.nil? || textile.empty?  # Add this check
  md = convert(textile, ctx)
  ...
end

Option 3: Add dedicated Settings configuration

{
  "skip_settings": true,
  "from_formatting": "textile",
  "to_formatting": "common_mark",
  "converters": "TextileToMarkdown"
}

Impact

This issue blocks all Textile→Markdown conversions when:

  • Settings fields are empty (common in fresh installs)
  • Users want to skip Settings and only convert content (Issues, Wiki, etc.)
  • Converting from non-standard configurations

Related Issues

Proposed Fix

The cleanest solution appears to be Option 1 - make Settings respect the items filter like other objects do. This would:

  • Be consistent with the rest of the architecture
  • Allow users to explicitly include/exclude Settings
  • Not break existing behavior (Settings would still convert by default if no items filter specified)

Would you accept a PR implementing this? I'm willing to fork and implement if the approach seems reasonable.

Workaround

Currently, the only workaround is to:

  1. Set all Settings fields to have valid content that can be converted
  2. Or skip Textile→Markdown conversion entirely (Textile is still fully supported in Redmine 6.x)

Assessment for Local Fix

Looking at the code structure, this appears reasonably straightforward to fix:

Complexity: LOW-MEDIUM

Option 1 approach (recommended):

  1. Modify migrate_settings() to check if Settings are included in converter configuration
  2. Add Settings item matching to ConfiguredConverter.matches?()
  3. Estimated lines of code: ~10-15 lines

Files to modify:

Option 2 approach (simpler but less flexible):

  1. Just skip nil/empty Settings in migrate_setting()
  2. Estimated lines: ~2 lines

Recommendation: If you want to fork and fix locally, I'd suggest:

  1. Quick fix: Implement Option 2 (skip empty Settings) - 2 minute change
  2. Proper fix: Submit PR with Option 1 (respect items filter) - 30 minute change with tests

Would you like me to help implement either approach?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions