Class: Boson::Manager

Inherits:
Object
  • Object
show all
Defined in:
lib/boson/manager.rb

Overview

Handles loading of libraries and commands.

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.failed_librariesObject

:stopdoc:



27
28
29
# File 'lib/boson/manager.rb', line 27

def failed_libraries
  @failed_libraries
end

Class Method Details

.add_library(lib) ⇒ Object



31
32
33
34
# File 'lib/boson/manager.rb', line 31

def add_library(lib)
  Boson.libraries.delete(Boson.library(lib.name))
  Boson.libraries << lib
end

.after_loadObject



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/boson/manager.rb', line 98

def after_load
  create_commands(@library)
  add_library(@library)
  puts "Loaded library #{@library.name}" if @options[:verbose]
  (lib_dependencies[@library] || []).each do |e|
    create_commands(e)
    add_library(e)
    puts "Loaded library dependency #{e.name}" if @options[:verbose]
  end
  true
end

.before_create_commands(lib) ⇒ Object



110
111
112
# File 'lib/boson/manager.rb', line 110

def before_create_commands(lib)
  lib.is_a?(FileLibrary) && lib.module && Inspector.add_method_data_to_library(lib)
end

.check_for_uncreated_aliases(lib, commands) ⇒ Object



160
161
162
163
164
165
# File 'lib/boson/manager.rb', line 160

def check_for_uncreated_aliases(lib, commands)
  return if lib.is_a?(GemLibrary)
  if (found_commands = Boson.commands.select {|e| commands.include?(e.name)}) && found_commands.find {|e| e.alias }
    $stderr.puts "No aliases created for library #{lib.name} because it has no module"
  end
end

.create_class_aliases(mod, class_commands) ⇒ Object



151
152
153
154
155
156
157
158
# File 'lib/boson/manager.rb', line 151

def create_class_aliases(mod, class_commands)
  class_commands.dup.each {|k,v|
    if v.is_a?(Array)
      class_commands.delete(k).each {|e| class_commands[e] = "#{k}.#{e}"}
    end
  }
  Alias.manager.create_aliases(:any_to_instance_method, mod.to_s=>class_commands.invert)
end

.create_command_aliases(lib, commands) ⇒ Object



131
132
133
# File 'lib/boson/manager.rb', line 131

def create_command_aliases(lib, commands)
  lib.module ? prep_and_create_instance_aliases(commands, lib.module) : check_for_uncreated_aliases(lib, commands)
end

.create_commands(lib, commands = lib.commands) ⇒ Object



114
115
116
117
118
119
# File 'lib/boson/manager.rb', line 114

def create_commands(lib, commands=lib.commands)
  before_create_commands(lib)
  commands.each {|e| Boson.commands << Command.create(e, lib)}
  create_command_aliases(lib, commands) if commands.size > 0 && !lib.no_alias_creation
  redefine_commands(lib, commands)
end

.create_instance_aliases(aliases_hash) ⇒ Object



147
148
149
# File 'lib/boson/manager.rb', line 147

def create_instance_aliases(aliases_hash)
  Alias.manager.create_aliases(:instance_method, aliases_hash)
end

.lib_dependenciesObject



81
82
83
# File 'lib/boson/manager.rb', line 81

def lib_dependencies
  @lib_dependencies ||= {}
end

.load(libraries, options = {}) ⇒ Object

Loads a library or an array of libraries with options. Manager loads the first library subclass to meet a library subclass’ criteria in this order: ModuleLibrary, FileLibrary, GemLibrary, RequireLibrary.

Examples:

Manager.load 'my_commands'  -> Loads a FileLibrary object from ~/.boson/commands/my_commands.rb
Manager.load 'method_lister' -> Loads a GemLibrary object which requires the method_lister gem

Any options that aren’t listed here are passed as library attributes to the libraries (see Library.new)

Options:

:verbose

Boolean to print each library’s loaded status along with more verbose errors. Default is false.



20
21
22
23
24
# File 'lib/boson/manager.rb', line 20

def load(libraries, options={})
  Array(libraries).map {|e|
    (@library = load_once(e, options)) ? after_load : false
  }.all?
end

.load_dependencies(lib, options = {}) ⇒ Object



85
86
87
88
89
90
91
# File 'lib/boson/manager.rb', line 85

def load_dependencies(lib, options={})
  lib_dependencies[lib] = Array(lib.dependencies).map do |e|
    next if loaded?(e)
    load_once(e, options.merge(:dependency=>true)) ||
      raise(LoaderError, "Can't load dependency #{e}")
  end.compact
end

.load_once(source, options = {}) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/boson/manager.rb', line 62

def load_once(source, options={})
  @options = options
  rescue_load_action(source, :load) do
    lib = loader_create(source)
    if loaded?(lib.name)
      $stderr.puts "Library #{lib.name} already exists." if options[:verbose] && !options[:dependency]
      false
    else
      if lib.load { load_dependencies(lib, options) }
        lib
      else
        $stderr.puts "Library #{lib.name} did not load successfully." if !options[:dependency]
        $stderr.puts "  "+lib.inspect if Runner.debug
        false
      end
    end
  end
end

.loaded?(lib_name) ⇒ Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/boson/manager.rb', line 36

def loaded?(lib_name)
  ((lib = Boson.library(lib_name)) && lib.loaded) ? true : false
end

.loader_create(source) ⇒ Object



93
94
95
96
# File 'lib/boson/manager.rb', line 93

def loader_create(source)
  lib_class = Library.handle_blocks.find {|k,v| v.call(source) } or raise(LoaderError, "Library #{source} not found.")
  lib_class[0].new(@options.merge(:name=>source))
end

.prep_and_create_instance_aliases(commands, lib_module) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
# File 'lib/boson/manager.rb', line 135

def prep_and_create_instance_aliases(commands, lib_module)
  aliases_hash = {}
  select_commands = Boson.commands.select {|e| commands.include?(e.name)}
  select_commands.each do |e|
    if e.alias
      aliases_hash[lib_module.to_s] ||= {}
      aliases_hash[lib_module.to_s][e.name] = e.alias
    end
  end
  create_instance_aliases(aliases_hash)
end

.redefine_commands(lib, commands) ⇒ Object



121
122
123
124
125
126
127
128
129
# File 'lib/boson/manager.rb', line 121

def redefine_commands(lib, commands)
  option_commands = lib.command_objects(commands).select {|e| e.option_command? }
  accepted, rejected = option_commands.partition {|e| e.args(lib) || e.arg_size }
  if @options[:verbose] && rejected.size > 0
    puts "Following commands cannot have options until their arguments are configured: " +
      rejected.map {|e| e.name}.join(', ')
  end
  accepted.each {|cmd| Scientist.redefine_command(lib.namespace_object, cmd) }
end

.rescue_load_action(library, load_method) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/boson/manager.rb', line 40

def rescue_load_action(library, load_method)
  yield
rescue AppendFeaturesFalseError
  warn "DEBUG: Library #{library} didn't load due to append_features" if Runner.debug
rescue LoaderError=>e
  FileLibrary.reset_file_cache(library.to_s)
  failed_libraries << library
  $stderr.puts "Unable to #{load_method} library #{library}. Reason: #{e.message}"
rescue StandardError, SyntaxError, LoadError =>e
  FileLibrary.reset_file_cache(library.to_s)
  failed_libraries << library
  message = "Unable to #{load_method} library #{library}. Reason: #{$!}"
  if Runner.debug
    message += "\n" + e.backtrace.map {|e| "  " + e }.join("\n")
  elsif @options[:verbose]
    message += "\n" + e.backtrace.slice(0,3).map {|e| "  " + e }.join("\n")
  end
  $stderr.puts message
ensure
  Inspector.disable if Inspector.enabled
end