Module: Legion::Extensions::Helpers::Base

Included in:
Cache, Core, Data, Knowledge, LLM, Logger, Task, Transport
Defined in:
lib/legion/extensions/helpers/base.rb

Constant Summary collapse

NAMESPACE_BOUNDARIES =

Words that mark the boundary between extension namespace segments and internal module structure. Segment extraction stops at these words.

%w[Actor Actors Runners Helpers Transport Data].freeze

Instance Method Summary collapse

Instance Method Details

#actor_classObject



73
74
75
# File 'lib/legion/extensions/helpers/base.rb', line 73

def actor_class
  calling_class
end

#actor_constObject



81
82
83
# File 'lib/legion/extensions/helpers/base.rb', line 81

def actor_const
  @actor_const ||= calling_class_array.last
end

#actor_nameObject



77
78
79
# File 'lib/legion/extensions/helpers/base.rb', line 77

def actor_name
  @actor_name ||= calling_class_array.last.gsub(/(?<!^)[A-Z]/) { "_#{Regexp.last_match(0)}" }.downcase
end

#amqp_prefixObject



23
24
25
# File 'lib/legion/extensions/helpers/base.rb', line 23

def amqp_prefix
  Helpers::Segments.segments_to_amqp_prefix(segments)
end

#calling_classObject



65
66
67
# File 'lib/legion/extensions/helpers/base.rb', line 65

def calling_class
  @calling_class ||= respond_to?(:ancestors) ? ancestors.first : self.class
end

#calling_class_arrayObject



69
70
71
# File 'lib/legion/extensions/helpers/base.rb', line 69

def calling_class_array
  @calling_class_array ||= calling_class.to_s.split('::')
end

#from_json(string) ⇒ Object



114
115
116
# File 'lib/legion/extensions/helpers/base.rb', line 114

def from_json(string)
  Legion::JSON.load(string)
end

#full_pathObject Also known as: extension_path



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/legion/extensions/helpers/base.rb', line 97

def full_path
  @full_path ||= begin
    base_name = segments.join('-')
    gem_name = "lex-#{base_name}"
    gem_dir = begin
      Gem::Specification.find_by_name(gem_name).gem_dir
    rescue Gem::MissingSpecError
      Gem::Specification.find_by_name("lex-#{base_name.tr('_', '-')}").gem_dir
    end
    require_path = Helpers::Segments.derive_require_path(gem_name)
    "#{gem_dir}/lib/#{require_path}"
  end
rescue Gem::MissingSpecError => e
  Legion::Logging.error "#{e.class} => #{e.message}"
end

#lex_classObject Also known as: extension_class



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/legion/extensions/helpers/base.rb', line 35

def lex_class
  @lex_class ||= begin
    parts = calling_class_array
    ext_idx = parts.index('Extensions')
    # All LEX extensions must be under Legion::Extensions::. If 'Extensions'
    # is not present, this is a misconfigured caller — fail loudly.
    raise ArgumentError, "#{calling_class} is not under Legion::Extensions namespace" unless ext_idx

    end_idx = ext_idx + 1
    end_idx += 1 while end_idx < parts.length && !NAMESPACE_BOUNDARIES.include?(parts[end_idx])
    # NameError cannot occur here: lex_class is only ever called from autobuild,
    # build_transport, build_runners, build_actors, and transport helpers — all of
    # which execute while the extension module is already required and fully defined.
    # The constant we resolve (e.g. Legion::Extensions::Http) is the very module
    # that owns this method, so it must already exist.
    Kernel.const_get(parts[0...end_idx].join('::'))
  end
end

#lex_constObject



61
62
63
# File 'lib/legion/extensions/helpers/base.rb', line 61

def lex_const
  @lex_const ||= lex_class.to_s.split('::').last
end

#lex_nameObject Also known as: extension_name, lex_filename



55
56
57
# File 'lib/legion/extensions/helpers/base.rb', line 55

def lex_name
  segments.join('_')
end

#lex_slugObject



15
16
17
# File 'lib/legion/extensions/helpers/base.rb', line 15

def lex_slug
  segments.join('.')
end

#log_tagObject



19
20
21
# File 'lib/legion/extensions/helpers/base.rb', line 19

def log_tag
  Helpers::Segments.segments_to_log_tag(segments)
end

#normalize(thing) ⇒ Object



118
119
120
121
122
123
124
# File 'lib/legion/extensions/helpers/base.rb', line 118

def normalize(thing)
  if thing.is_a? String
    to_json(from_json(thing))
  else
    from_json(to_json(thing))
  end
end

#runner_classObject



85
86
87
# File 'lib/legion/extensions/helpers/base.rb', line 85

def runner_class
  @runner_class ||= Kernel.const_get(actor_class.to_s.sub(/Actor$/, 'Runners'))
end

#runner_constObject



93
94
95
# File 'lib/legion/extensions/helpers/base.rb', line 93

def runner_const
  @runner_const ||= runner_class.to_s.split('::').last
end

#runner_nameObject



89
90
91
# File 'lib/legion/extensions/helpers/base.rb', line 89

def runner_name
  @runner_name ||= runner_class.to_s.split('::').last.gsub(/(?<!^)[A-Z]/) { "_#{Regexp.last_match(0)}" }.downcase
end

#segmentsObject



11
12
13
# File 'lib/legion/extensions/helpers/base.rb', line 11

def segments
  @segments ||= derive_segments_from_namespace
end

#settings_pathObject



27
28
29
# File 'lib/legion/extensions/helpers/base.rb', line 27

def settings_path
  Helpers::Segments.segments_to_settings_path(segments)
end

#table_prefixObject



31
32
33
# File 'lib/legion/extensions/helpers/base.rb', line 31

def table_prefix
  Helpers::Segments.segments_to_table_prefix(segments)
end

#to_dotted_hash(hash, recursive_key = '') ⇒ Object



126
127
128
129
130
131
132
133
134
135
# File 'lib/legion/extensions/helpers/base.rb', line 126

def to_dotted_hash(hash, recursive_key = '')
  hash.each_with_object({}) do |(k, v), ret|
    key = recursive_key + k.to_s
    if v.is_a? Hash
      ret.merge! to_dotted_hash(v, "#{key}.")
    else
      ret[key.to_sym] = v
    end
  end
end