Class: Metasploit::Concern::Loader

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::Validations
Defined in:
lib/metasploit/concern/loader.rb

Overview

Loads ActiveSupport::Concerns (or anything that can be passed to ‘include` really) under #root

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes = {}) ⇒ Loader

Returns a new instance of Loader.

Parameters:

  • attributes (Hash{Symbol => String,nil}) (defaults to: {})


56
57
58
59
60
# File 'lib/metasploit/concern/loader.rb', line 56

def initialize(attributes={})
  attributes.each do |attribute, value|
    public_send("#{attribute}=", value)
  end
end

Instance Attribute Details

#rootPathname

Pathname under which to find concerns.

Returns:

  • (Pathname)


13
14
15
# File 'lib/metasploit/concern/loader.rb', line 13

def root
  @root
end

Instance Method Details

#each_pathname_constant(mechanism:, parent_pathname:) {|constant| ... } ⇒ void

This method returns an undefined value.

Yields each constant under ‘parent_pathname`.

Parameters:

  • mechanism (:constantize, :require)

    ‘:require` if child pathname should be required so that the constant cannot be unloaded by `ActiveSupport::Dependencies.clear`.

  • parent_pathname (Pathname)

Yields:

  • (constant)

Yield Parameters:

  • constant (Module)

    constant declared under ‘parent_pathname`.

Yield Returns:

  • (void)


35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/metasploit/concern/loader.rb', line 35

def each_pathname_constant(mechanism:, parent_pathname:)
  parent_pathname.each_child do |child_pathname|
    constant = constantize_pathname(
        mechanism: mechanism,
        pathname: child_pathname
    )

    if constant
      yield constant
    end
  end
end

#globPathname

Glob pattern for concerns.

Returns:

  • (Pathname)


51
52
53
# File 'lib/metasploit/concern/loader.rb', line 51

def glob
  root.join('**', '*.rb')
end

#module_pathname_setSet<Pathname>

Set of Pathnames for ‘Module`s that will have concerns included.

Returns:

  • (Set<Pathname>)


65
66
67
68
69
70
71
72
73
74
# File 'lib/metasploit/concern/loader.rb', line 65

def module_pathname_set
  concern_paths = Dir.glob(glob)

  concern_paths.each_with_object(Set.new) { |concern_path, module_pathname_set|
    concern_pathname = Pathname.new(concern_path)
    module_pathname = concern_pathname.parent

    module_pathname_set.add module_pathname
  }
end

#registervoid

This method returns an undefined value.

Registers load hooks with ‘ActiveSupport.on_load`.



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/metasploit/concern/loader.rb', line 79

def register
  module_pathname_set.each do |module_pathname|
    relative_module_pathname = module_pathname.relative_path_from(root)
    relative_module_path = relative_module_pathname.to_path
    underscored_module_name = relative_module_path.gsub(File::SEPARATOR, '_')
    on_load_name = underscored_module_name.to_sym

    # on_load block is instance_evaled, so need to capture self
    loader = self

    ActiveSupport.on_load(on_load_name) do
      if ActiveSupport::Dependencies.autoloaded? self
        mechanism = :constantize
      else
        mechanism = :require
      end

      loader.each_pathname_constant(mechanism: mechanism, parent_pathname: module_pathname) do |concern|
        include concern
      end
    end
  end
end