Class: Ace::Git::Molecules::ConfigLoader

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/git/molecules/config_loader.rb

Overview

Load and merge diff configuration from cascade Follows ADR-022: Configuration Default and Override Pattern Uses Config.merge() for consistent merge strategy support Migrated from ace-git-diff

Class Method Summary collapse

Class Method Details

.extract_diff_config(config) ⇒ Hash

Extract diff configuration from various config formats Supports both diff: key and legacy/direct formats When config contains both top-level diff keys AND a nested diff: section, merges them (nested overrides top-level) to preserve defaults

Parameters:

  • config (Hash)

    Configuration hash

Returns:

  • (Hash)

    Extracted diff configuration



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/ace/git/molecules/config_loader.rb', line 63

def extract_diff_config(config)
  return {} if config.nil? || config.empty?

  # First, collect any top-level diff keys (flattened defaults)
  diff_keys = %w[exclude_patterns exclude_whitespace exclude_renames
    exclude_moves max_lines ranges paths since format timeout grouped_stats]
  diff_sym_keys = diff_keys.map(&:to_sym)

  top_level_diff = {}
  diff_keys.each { |k| top_level_diff[k] = config[k] if config.key?(k) }
  diff_sym_keys.each { |k| top_level_diff[k.to_s] = config[k] if config.key?(k) }

  # Check for explicit diff: key (nested under git: from config cascade)
  if config.key?("diff") || config.key?(:diff)
    diff_config = config["diff"] || config[:diff]
    if diff_config.is_a?(Hash)
      # Merge nested diff over top-level using Config.merge()
      return Ace::Support::Config::Models::Config.new(top_level_diff, source: "git_diff_extract")
          .merge(diff_config)
          .to_h
    end
  end

  # Return top-level diff keys if we found any
  return top_level_diff unless top_level_diff.empty?

  # Check for legacy diffs: array format
  if config.key?("diffs") || config.key?(:diffs)
    diffs = config["diffs"] || config[:diffs]
    return {"ranges" => Array(diffs)} if diffs
  end

  # Check for legacy filters format (ace-docs)
  if config.key?("filters") || config.key?(:filters)
    filters = config["filters"] || config[:filters]
    return {"paths" => Array(filters)} if filters
  end

  # No diff config found
  {}
end

.load(instance_config = {}) ⇒ Models::DiffConfig

Load configuration using ace-config cascade with deep merge Priority: instance_config merged over global config (which is already defaults + user)

Parameters:

  • instance_config (Hash) (defaults to: {})

    Instance-level configuration (highest priority)

Returns:



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/ace/git/molecules/config_loader.rb', line 18

def load(instance_config = {})
  # Get global config from ace-git (already merged defaults + user per ADR-022)
  global_config = Ace::Git.config || {}

  # Extract diff config from the global config (handles diff: namespace)
  global_diff_config = extract_diff_config(global_config)

  # Use Config.merge() for consistent merge strategy support
  # This enables future per-key merge strategies via _merge directive
  config_hash = Ace::Support::Config::Models::Config.new(global_diff_config, source: "git_global")
    .merge(instance_config)
    .to_h

  Models::DiffConfig.from_hash(config_hash)
end

.load_for_gem(gem_config, instance_config = {}) ⇒ Models::DiffConfig

Load configuration for a specific gem integration Priority: instance_config > gem_config > global_config (all deep merged)

Parameters:

  • gem_config (Hash)

    Gem-specific configuration

  • instance_config (Hash) (defaults to: {})

    Instance-level overrides

Returns:



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/ace/git/molecules/config_loader.rb', line 39

def load_for_gem(gem_config, instance_config = {})
  # Start with global config (already merged defaults + user per ADR-022)
  global_config = Ace::Git.config || {}

  # Extract diff config from global (handles diff: namespace)
  global_diff_config = extract_diff_config(global_config)
  gem_diff_config = extract_diff_config(gem_config)

  # Use Config.merge() cascade: global -> gem -> instance
  # This enables future per-key merge strategies via _merge directive
  config_hash = Ace::Support::Config::Models::Config.new(global_diff_config, source: "git_global")
    .merge(gem_diff_config)
    .merge(instance_config)
    .to_h

  Models::DiffConfig.from_hash(config_hash)
end