Module: Familia::Features::Autoloader

Included in:
Familia::Features
Defined in:
lib/familia/features/autoloader.rb

Overview

Provides autoloading functionality for Ruby files based on patterns and conventions.

Used by the Features module at library startup to load feature files, and available as a utility for other modules requiring file autoloading capabilities.

Class Method Summary collapse

Class Method Details

.autoload_files(patterns, exclude: [], log_prefix: 'Autoloader') ⇒ Object

Autoloads Ruby files matching the given patterns.

Parameters:

  • patterns (String, Array<String>)

    file patterns to match (supports Dir.glob patterns)

  • exclude (Array<String>) (defaults to: [])

    basenames to exclude from loading

  • log_prefix (String) (defaults to: 'Autoloader')

    prefix for debug logging messages



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/familia/features/autoloader.rb', line 46

def self.autoload_files(patterns, exclude: [], log_prefix: 'Autoloader')
  patterns = Array(patterns)

  patterns.each do |pattern|
    Familia.trace :AUTOLOAD, nil, "[#{log_prefix}] Autoloader loading features from #{pattern}"
    Dir.glob(pattern).each do |file_path|
      basename = File.basename(file_path)

      # Skip excluded files
      next if exclude.include?(basename)

      Familia.trace :FEATURE, nil, "[#{log_prefix}] Loading #{basename}" if Familia.debug?
      require File.expand_path(file_path)
    end
  end
end

.included(base) ⇒ Object

Autoloads feature files when this module is included.

Discovers and loads all Ruby files in the features/ directory relative to the including module's location. Typically used by Familia::Features.

Parameters:

  • base (Module)

    the module including this autoloader



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/familia/features/autoloader.rb', line 20

def self.included(base)
  # Get the directory where the including module is defined
  # This should be lib/familia for the Features module
  base_path = File.dirname(caller_locations(1, 1).first.path)
  config_name = normalize_to_config_name(base.name)

  dir_patterns = [
    File.join(base_path, 'features', '*.rb'),
    File.join(base_path, config_name, 'features', '*.rb'),
    File.join(base_path, config_name, 'features.rb'),
  ]

  # Ensure the Features module exists within the base module
  unless base.const_defined?(:Features) || config_name.eql?('features')
    base.const_set(:Features, Module.new)
  end

  # Use the shared autoload_files method
  autoload_files(dir_patterns, log_prefix: "Autoloader[#{config_name}]")
end

.normalize_to_config_name(value) ⇒ String

Converts the value into a string that can be used to look up configuration values or system paths. This replicates the normalization done by the Familia::Horreum model class config_name method.

NOTE: We don't call that existing method directly b/c Autoloader is meant to work for any class/module that matches dir_patterns (see included).

Parameters:

  • value (String)

    the value to normalize (typically a class name)

Returns:

  • (String)

    the underscored value as a string

See Also:

  • Horreum::DefinitionMethods#config_name


75
76
77
78
79
# File 'lib/familia/features/autoloader.rb', line 75

def normalize_to_config_name(value)
  return nil if value.nil?

  value.demodularize.snake_case
end