Class: Toys::Loader
- Inherits:
-
Object
- Object
- Toys::Loader
- Defined in:
- lib/toys/loader.rb
Overview
The Loader service loads tools from configuration files, and finds the appropriate tool given a set of command line arguments.
Instance Method Summary collapse
-
#add_block(high_priority: false, path: nil, &block) ⇒ Object
Add a configuration block to the loader.
-
#add_path(path, high_priority: false) ⇒ Object
Add a configuration file/directory to the loader.
-
#has_subtools?(words) ⇒ Boolean
Returns true if the given path has at least one subtool.
-
#initialize(index_file_name: nil, middleware_stack: [], mixin_lookup: nil, middleware_lookup: nil, template_lookup: nil) ⇒ Loader
constructor
Create a Loader.
-
#list_subtools(words, recursive: false) ⇒ Array<Toys::Definition::Tool,Toys::Definition::Alias>
Returns a list of subtools for the given path, loading from the configuration if necessary.
-
#lookup(args) ⇒ Array(Toys::Definition::Tool,Array<String>)
Given a list of command line arguments, find the appropriate tool to handle the command, loading it from the configuration if necessary, and following aliases.
-
#resolve_standard_mixin(name) ⇒ Module?
Attempt to get a well-known mixin module for the given symbolic name.
-
#resolve_standard_template(name) ⇒ Class?
Attempt to get a well-known template class for the given symbolic name.
Constructor Details
#initialize(index_file_name: nil, middleware_stack: [], mixin_lookup: nil, middleware_lookup: nil, template_lookup: nil) ⇒ Loader
Create a Loader
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/toys/loader.rb', line 65 def initialize(index_file_name: nil, middleware_stack: [], mixin_lookup: nil, middleware_lookup: nil, template_lookup: nil) if index_file_name && ::File.extname(index_file_name) != ".rb" raise ::ArgumentError, "Illegal index file name #{index_file_name.inspect}" end @mixin_lookup = mixin_lookup || Utils::ModuleLookup.new @middleware_lookup = middleware_lookup || Utils::ModuleLookup.new @template_lookup = template_lookup || Utils::ModuleLookup.new @index_file_name = index_file_name @middleware_stack = middleware_stack @worklist = [] @tool_data = {} @max_priority = @min_priority = 0 get_tool_definition([], -999_999) end |
Instance Method Details
#add_block(high_priority: false, path: nil, &block) ⇒ Object
Add a configuration block to the loader.
108 109 110 111 112 113 |
# File 'lib/toys/loader.rb', line 108 def add_block(high_priority: false, path: nil, &block) path ||= "(Block #{block.object_id})" priority = high_priority ? (@max_priority += 1) : (@min_priority -= 1) @worklist << [block, path, [], priority] self end |
#add_path(path, high_priority: false) ⇒ Object
Add a configuration file/directory to the loader.
89 90 91 92 93 94 95 96 |
# File 'lib/toys/loader.rb', line 89 def add_path(path, high_priority: false) paths = Array(path) priority = high_priority ? (@max_priority += 1) : (@min_priority -= 1) paths.each do |p| @worklist << [:file, check_path(p), [], priority] end self end |
#has_subtools?(words) ⇒ Boolean
Returns true if the given path has at least one subtool. Loads from the configuration if necessary.
182 183 184 185 186 187 188 189 |
# File 'lib/toys/loader.rb', line 182 def has_subtools?(words) load_for_prefix(words) len = words.length @tool_data.each_key do |n| return true if !n.empty? && n.length > len && n.slice(0, len) == words end false end |
#list_subtools(words, recursive: false) ⇒ Array<Toys::Definition::Tool,Toys::Definition::Alias>
Returns a list of subtools for the given path, loading from the configuration if necessary.
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/toys/loader.rb', line 158 def list_subtools(words, recursive: false) load_for_prefix(words) found_tools = [] len = words.length @tool_data.each do |n, td| next if n.empty? if recursive next if n.length <= len || n.slice(0, len) != words else next unless n.slice(0..-2) == words end tool = td.active_definition || td.top_definition found_tools << tool unless tool.nil? end sort_tools_by_name(found_tools) end |
#lookup(args) ⇒ Array(Toys::Definition::Tool,Array<String>)
Given a list of command line arguments, find the appropriate tool to handle the command, loading it from the configuration if necessary, and following aliases. This always returns a tool. If the specific tool path is not defined and cannot be found in any configuration, it finds the nearest namespace that would contain that tool, up to the root tool.
Returns a tuple of the found tool, and the array of remaining arguments that are not part of the tool name and should be passed as tool args.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/toys/loader.rb', line 129 def lookup(args) orig_prefix = args.take_while { |arg| !arg.start_with?("-") } cur_prefix = orig_prefix loop do load_for_prefix(cur_prefix) p = orig_prefix loop do tool_definition = get_active_tool(p, []) if tool_definition finish_definitions_in_tree(tool_definition.full_name) return [tool_definition, args.slice(p.length..-1)] end break if p.empty? || p.length <= cur_prefix.length p = p.slice(0..-2) end raise "Unexpected error" if cur_prefix.empty? cur_prefix = cur_prefix.slice(0..-2) end end |
#resolve_standard_mixin(name) ⇒ Module?
Attempt to get a well-known mixin module for the given symbolic name.
273 274 275 |
# File 'lib/toys/loader.rb', line 273 def resolve_standard_mixin(name) @mixin_lookup.lookup(name) end |
#resolve_standard_template(name) ⇒ Class?
Attempt to get a well-known template class for the given symbolic name.
283 284 285 |
# File 'lib/toys/loader.rb', line 283 def resolve_standard_template(name) @template_lookup.lookup(name) end |