boson 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE.txt +22 -0
- data/README.rdoc +133 -0
- data/Rakefile +52 -0
- data/VERSION.yml +4 -0
- data/bin/boson +6 -0
- data/lib/boson.rb +72 -0
- data/lib/boson/command.rb +117 -0
- data/lib/boson/commands.rb +7 -0
- data/lib/boson/commands/core.rb +66 -0
- data/lib/boson/commands/web_core.rb +36 -0
- data/lib/boson/index.rb +95 -0
- data/lib/boson/inspector.rb +80 -0
- data/lib/boson/inspectors/argument_inspector.rb +92 -0
- data/lib/boson/inspectors/comment_inspector.rb +79 -0
- data/lib/boson/inspectors/method_inspector.rb +94 -0
- data/lib/boson/libraries/file_library.rb +76 -0
- data/lib/boson/libraries/gem_library.rb +21 -0
- data/lib/boson/libraries/module_library.rb +17 -0
- data/lib/boson/libraries/require_library.rb +11 -0
- data/lib/boson/library.rb +108 -0
- data/lib/boson/loader.rb +103 -0
- data/lib/boson/manager.rb +184 -0
- data/lib/boson/namespace.rb +45 -0
- data/lib/boson/option_parser.rb +318 -0
- data/lib/boson/repo.rb +38 -0
- data/lib/boson/runner.rb +51 -0
- data/lib/boson/runners/bin_runner.rb +100 -0
- data/lib/boson/runners/repl_runner.rb +40 -0
- data/lib/boson/scientist.rb +168 -0
- data/lib/boson/util.rb +93 -0
- data/lib/boson/view.rb +31 -0
- data/test/argument_inspector_test.rb +62 -0
- data/test/bin_runner_test.rb +136 -0
- data/test/commands_test.rb +51 -0
- data/test/comment_inspector_test.rb +99 -0
- data/test/config/index.marshal +0 -0
- data/test/file_library_test.rb +50 -0
- data/test/index_test.rb +117 -0
- data/test/loader_test.rb +181 -0
- data/test/manager_test.rb +110 -0
- data/test/method_inspector_test.rb +64 -0
- data/test/option_parser_test.rb +365 -0
- data/test/repo_test.rb +22 -0
- data/test/runner_test.rb +43 -0
- data/test/scientist_test.rb +291 -0
- data/test/test_helper.rb +119 -0
- metadata +133 -0
@@ -0,0 +1,76 @@
|
|
1
|
+
module Boson
|
2
|
+
# This library loads a file in the commands subdirectory of a Boson::Repo. This library looks for files
|
3
|
+
# in repositories in the order given by Boson.repos.
|
4
|
+
# TODO: explain file format, modules, inspectors
|
5
|
+
class FileLibrary < Library
|
6
|
+
#:stopdoc:
|
7
|
+
def self.library_file(library, dir)
|
8
|
+
File.join(Repo.commands_dir(dir), library + ".rb")
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.matched_repo; @repo; end
|
12
|
+
|
13
|
+
def self.read_library_file(file, reload=false)
|
14
|
+
@file_cache ||= {}
|
15
|
+
@file_cache[file] = File.read(file) if (!@file_cache.has_key?(file) || reload)
|
16
|
+
@file_cache[file]
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.reset_file_cache(name=nil)
|
20
|
+
if name && @file_cache
|
21
|
+
#td: tia other repos
|
22
|
+
@file_cache.delete(library_file(name, Boson.repo.dir))
|
23
|
+
else
|
24
|
+
@file_cache = nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
handles {|source|
|
29
|
+
@repo = Boson.repos.find {|e|
|
30
|
+
File.exists? library_file(source.to_s, e.dir)
|
31
|
+
}
|
32
|
+
!!@repo
|
33
|
+
}
|
34
|
+
|
35
|
+
def library_file
|
36
|
+
self.class.library_file(@name, @repo_dir)
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_repo
|
40
|
+
self.class.matched_repo
|
41
|
+
end
|
42
|
+
|
43
|
+
def load_source(reload=false)
|
44
|
+
library_string = self.class.read_library_file(library_file, reload)
|
45
|
+
Inspector.enable
|
46
|
+
Commands.module_eval(library_string, library_file)
|
47
|
+
Inspector.disable
|
48
|
+
end
|
49
|
+
|
50
|
+
def load_source_and_set_module
|
51
|
+
detected = detect_additions(:modules=>true) { load_source }
|
52
|
+
@module = determine_lib_module(detected[:modules]) unless @module
|
53
|
+
end
|
54
|
+
|
55
|
+
def reload_source_and_set_module
|
56
|
+
detected = detect_additions(:modules=>true) { load_source(true) }
|
57
|
+
if (@new_module = !detected[:modules].empty?)
|
58
|
+
@commands = []
|
59
|
+
@module = determine_lib_module(detected[:modules])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def determine_lib_module(detected_modules)
|
64
|
+
case detected_modules.size
|
65
|
+
when 1 then lib_module = detected_modules[0]
|
66
|
+
when 0 then raise LoaderError, "Can't detect module. Make sure at least one module is defined in the library."
|
67
|
+
else
|
68
|
+
unless ((lib_module = Util.constantize("boson/commands/#{@name}")) && lib_module.to_s[/^Boson::Commands/])
|
69
|
+
raise LoaderError, "Can't detect module. Specify a module in this library's config."
|
70
|
+
end
|
71
|
+
end
|
72
|
+
lib_module
|
73
|
+
end
|
74
|
+
#:startdoc:
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Boson
|
2
|
+
# This library loads a gem by the given name. Unlike FileLibrary or ModuleLibrary, this library
|
3
|
+
# doesn't need a module to provide its functionality.
|
4
|
+
class GemLibrary < Library
|
5
|
+
#:stopdoc:
|
6
|
+
def self.is_a_gem?(name)
|
7
|
+
Object.const_defined?(:Gem) && Gem.searcher.find(name).is_a?(Gem::Specification)
|
8
|
+
end
|
9
|
+
|
10
|
+
handles {|source| is_a_gem?(source.to_s) }
|
11
|
+
|
12
|
+
def loaded_correctly?
|
13
|
+
!@gems.empty? || !@commands.empty? || !!@module
|
14
|
+
end
|
15
|
+
|
16
|
+
def load_source_and_set_module
|
17
|
+
detect_additions { Util.safe_require @name }
|
18
|
+
end
|
19
|
+
#:startdoc:
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Boson
|
2
|
+
# A library which takes a module as a library's name. Reload for this library
|
3
|
+
# subclass is disabled.
|
4
|
+
class ModuleLibrary < Library
|
5
|
+
#:stopdoc:
|
6
|
+
handles {|source| source.is_a?(Module) }
|
7
|
+
|
8
|
+
def set_name(name)
|
9
|
+
@module = name
|
10
|
+
underscore_lib = name.to_s[/^Boson::Commands/] ? name.to_s.split('::')[-1] : name.to_s
|
11
|
+
super Util.underscore(underscore_lib)
|
12
|
+
end
|
13
|
+
|
14
|
+
def reload; false; end
|
15
|
+
#:startdoc:
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# This library requires the given name. This is useful for loading standard libraries,
|
2
|
+
# non-gem libraries (i.e. rip packages) and anything else in $LOAD_PATH.
|
3
|
+
class Boson::RequireLibrary < Boson::GemLibrary
|
4
|
+
handles {|source|
|
5
|
+
begin
|
6
|
+
Kernel.load("#{source}.rb", true)
|
7
|
+
rescue LoadError
|
8
|
+
false
|
9
|
+
end
|
10
|
+
}
|
11
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Boson
|
2
|
+
# A library is a group of commands (Command objects) usually grouped together by a module.
|
3
|
+
# Libraries are loaded from different sources depending on the library subclass. Default library
|
4
|
+
# subclasses are FileLibrary, GemLibrary, RequireLibrary and ModuleLibrary.
|
5
|
+
#
|
6
|
+
# To create your own subclass you need to define what sources the subclass can handle with handles().
|
7
|
+
# If handles() returns true then the subclass is chosen to load. See Loader to see what instance methods
|
8
|
+
# to override for a subclass.
|
9
|
+
class Library
|
10
|
+
include Loader
|
11
|
+
class <<self
|
12
|
+
#:stopdoc:
|
13
|
+
attr_accessor :handle_blocks
|
14
|
+
def handles(&block)
|
15
|
+
(Library.handle_blocks ||= []) << [self,block]
|
16
|
+
end
|
17
|
+
#:startdoc:
|
18
|
+
end
|
19
|
+
|
20
|
+
# Public attributes for use outside of Boson.
|
21
|
+
ATTRIBUTES = [:gems, :dependencies, :commands, :loaded, :module, :name, :namespace]
|
22
|
+
attr_reader *(ATTRIBUTES + [:commands_hash, :library_file, :object_namespace])
|
23
|
+
# Private attribute for use within Boson.
|
24
|
+
attr_reader :except, :no_alias_creation, :new_module, :new_commands
|
25
|
+
# Optional namespace name for a library. When enabled defaults to a library's name.
|
26
|
+
attr_writer :namespace
|
27
|
+
# Creates a library object with a hash of attributes which must include a :name attribute.
|
28
|
+
# Each hash pair maps directly to an instance variable and value. Defaults for attributes
|
29
|
+
# are read from config[:libraries][@library_name]. See Boson::Repo.config for more details.
|
30
|
+
def initialize(hash)
|
31
|
+
@name = set_name hash.delete(:name)
|
32
|
+
@loaded = false
|
33
|
+
repo = set_repo
|
34
|
+
@repo_dir = repo.dir
|
35
|
+
@commands_hash = {}
|
36
|
+
@commands = []
|
37
|
+
set_config (repo.config[:libraries][@name] || {}).merge(hash)
|
38
|
+
@commands_hash = repo.config[:commands].merge @commands_hash
|
39
|
+
set_command_aliases(repo.config[:command_aliases])
|
40
|
+
@namespace = true if Boson.repo.config[:auto_namespace] && @namespace.nil? &&
|
41
|
+
!Boson::Runner.default_libraries.include?(@module)
|
42
|
+
@namespace = clean_name if @namespace
|
43
|
+
end
|
44
|
+
|
45
|
+
# A concise symbol version of a library type i.e. FileLibrary -> :file.
|
46
|
+
def library_type
|
47
|
+
str = self.class.to_s[/::(\w+)Library$/, 1] || 'library'
|
48
|
+
str.downcase.to_sym
|
49
|
+
end
|
50
|
+
|
51
|
+
# The object a library uses for executing its commands.
|
52
|
+
def namespace_object
|
53
|
+
@namespace_object ||= @namespace ? Boson.invoke(@namespace) : Boson.main_object
|
54
|
+
end
|
55
|
+
|
56
|
+
#:stopdoc:
|
57
|
+
# handles names under directories
|
58
|
+
def clean_name
|
59
|
+
@name[/\w+$/]
|
60
|
+
end
|
61
|
+
|
62
|
+
def set_name(name)
|
63
|
+
name.to_s or raise ArgumentError, "New library missing required key :name"
|
64
|
+
end
|
65
|
+
|
66
|
+
def set_config(config)
|
67
|
+
if (commands = config.delete(:commands))
|
68
|
+
if commands.is_a?(Array)
|
69
|
+
@commands += commands
|
70
|
+
@pre_defined_commands = true
|
71
|
+
elsif commands.is_a?(Hash)
|
72
|
+
@commands += commands.keys
|
73
|
+
@commands_hash = Util.recursive_hash_merge commands, @commands_hash
|
74
|
+
end
|
75
|
+
end
|
76
|
+
set_command_aliases config.delete(:command_aliases) if config[:command_aliases]
|
77
|
+
set_attributes config, true
|
78
|
+
end
|
79
|
+
|
80
|
+
def set_command_aliases(command_aliases)
|
81
|
+
(command_aliases || {}).each do |cmd, cmd_alias|
|
82
|
+
@commands_hash[cmd] ||= {}
|
83
|
+
@commands_hash[cmd][:alias] ||= cmd_alias
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def set_repo
|
88
|
+
Boson.repo
|
89
|
+
end
|
90
|
+
|
91
|
+
def set_attributes(hash, force=false)
|
92
|
+
hash.each {|k,v| instance_variable_set("@#{k}", v) if instance_variable_get("@#{k}").nil? || force }
|
93
|
+
end
|
94
|
+
|
95
|
+
def command_objects(names)
|
96
|
+
Boson.commands.select {|e| names.include?(e.name) && e.lib == self.name }
|
97
|
+
end
|
98
|
+
|
99
|
+
def marshal_dump
|
100
|
+
[@name, @commands, @gems, @module.to_s, @repo_dir]
|
101
|
+
end
|
102
|
+
|
103
|
+
def marshal_load(ary)
|
104
|
+
@name, @commands, @gems, @module, @repo_dir = ary
|
105
|
+
end
|
106
|
+
#:startdoc:
|
107
|
+
end
|
108
|
+
end
|
data/lib/boson/loader.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
module Boson
|
2
|
+
# Raised if a library has a method which conflicts with existing methods in Boson.main_object.
|
3
|
+
class MethodConflictError < LoaderError; end
|
4
|
+
|
5
|
+
# This module is mixed into Library to give it load() and reload() functionality.
|
6
|
+
# When creating your own Library subclass, you should override load_source_and_set_module and
|
7
|
+
# reload_source_and_set_module. You can override other methods in this module as needed.
|
8
|
+
module Loader
|
9
|
+
# Loads a library and its dependencies and returns true if library loads correctly.
|
10
|
+
def load
|
11
|
+
@gems ||= []
|
12
|
+
load_source_and_set_module
|
13
|
+
module_callbacks if @module
|
14
|
+
yield if block_given?
|
15
|
+
(@module || @class_commands) ? detect_additions { load_module_commands } : @namespace = nil
|
16
|
+
@init_methods.each {|m| namespace_object.send(m) if namespace_object.respond_to?(m) } if @init_methods && !@index
|
17
|
+
set_library_commands
|
18
|
+
loaded_correctly? && (@loaded = true)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Load the source and set instance variables necessary to make a library valid i.e. @module.
|
22
|
+
def load_source_and_set_module; end
|
23
|
+
|
24
|
+
# Boolean which indicates if library loaded correctly.
|
25
|
+
def loaded_correctly?
|
26
|
+
!!@module
|
27
|
+
end
|
28
|
+
|
29
|
+
# Reloads a library from its source and adds new commands.
|
30
|
+
def reload
|
31
|
+
original_commands = @commands
|
32
|
+
reload_source_and_set_module
|
33
|
+
detect_additions { load_module_commands } if @new_module
|
34
|
+
@new_commands = @commands - original_commands
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
# Same as load_source_and_set_module except it reloads.
|
39
|
+
def reload_source_and_set_module
|
40
|
+
raise LoaderError, "Reload not implemented"
|
41
|
+
end
|
42
|
+
|
43
|
+
#:stopdoc:
|
44
|
+
def module_callbacks
|
45
|
+
set_config(@module.config) if @module.respond_to?(:config)
|
46
|
+
if @module.respond_to?(:append_features)
|
47
|
+
raise AppendFeaturesFalseError unless @module.append_features(Module.new)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def load_module_commands
|
52
|
+
initialize_library_module
|
53
|
+
rescue MethodConflictError=>e
|
54
|
+
if Boson.repo.config[:error_method_conflicts] || @namespace
|
55
|
+
raise MethodConflictError, e.message
|
56
|
+
else
|
57
|
+
@namespace = clean_name
|
58
|
+
$stderr.puts "#{e.message}. Attempting load into the namespace #{@namespace}..."
|
59
|
+
initialize_library_module
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def detect_additions(options={}, &block)
|
64
|
+
options[:object_methods] = @object_methods if !@object_methods.nil?
|
65
|
+
detected = Util.detect(options, &block)
|
66
|
+
@gems += detected[:gems] if detected[:gems]
|
67
|
+
@commands += detected[:methods]
|
68
|
+
detected
|
69
|
+
end
|
70
|
+
|
71
|
+
def initialize_library_module
|
72
|
+
@module = @module ? Util.constantize(@module) : Util.create_module(Boson::Commands, clean_name)
|
73
|
+
raise(LoaderError, "No module for library #{@name}") unless @module
|
74
|
+
Manager.create_class_aliases(@module, @class_commands) unless @class_commands.to_s.empty?
|
75
|
+
check_for_method_conflicts unless @force
|
76
|
+
@namespace = clean_name if @object_namespace
|
77
|
+
@namespace ? Namespace.create(@namespace, self) : include_in_universe
|
78
|
+
end
|
79
|
+
|
80
|
+
def include_in_universe(lib_module=@module)
|
81
|
+
Boson::Universe.send :include, lib_module
|
82
|
+
Boson::Universe.send :extend_object, Boson.main_object
|
83
|
+
end
|
84
|
+
|
85
|
+
def check_for_method_conflicts
|
86
|
+
conflicts = @namespace ? (Boson.can_invoke?(@namespace) ? [@namespace] : []) :
|
87
|
+
Util.common_instance_methods(@module, Boson::Universe)
|
88
|
+
unless conflicts.empty?
|
89
|
+
raise MethodConflictError,"The following commands conflict with existing commands: #{conflicts.join(', ')}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def set_library_commands
|
94
|
+
aliases = @commands_hash.select {|k,v| @commands.include?(k) }.map {|k,v| v[:alias]}.compact
|
95
|
+
@commands -= aliases
|
96
|
+
@commands.delete(@namespace) if @namespace
|
97
|
+
@commands += Boson.invoke(@namespace).boson_commands if @namespace && !@pre_defined_commands
|
98
|
+
@commands -= @except if @except
|
99
|
+
@commands.uniq!
|
100
|
+
end
|
101
|
+
#:startdoc:
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
module Boson
|
2
|
+
# Base class for library loading errors. Raised mostly in Boson::Loader and rescued by Boson::Manager.
|
3
|
+
class LoaderError < StandardError; end
|
4
|
+
# Raised when a library's append_features returns false.
|
5
|
+
class AppendFeaturesFalseError < StandardError; end
|
6
|
+
|
7
|
+
class Manager
|
8
|
+
class <<self
|
9
|
+
# Loads a library or an array of libraries with options. Manager loads the first library subclass
|
10
|
+
# to meet a library subclass' criteria in this order: ModuleLibrary, FileLibrary, GemLibrary, RequireLibrary.
|
11
|
+
# ==== Examples:
|
12
|
+
# Manager.load 'my_commands' -> Loads a FileLibrary object from ~/.boson/commands/my_commands.rb
|
13
|
+
# Manager.load 'method_lister' -> Loads a GemLibrary object which requires the method_lister gem
|
14
|
+
# ==== Options:
|
15
|
+
# [:verbose] Boolean to print each library's loaded status along with more verbose errors. Default is false.
|
16
|
+
# [:index] Boolean to load in index mode. Default is false.
|
17
|
+
def load(libraries, options={})
|
18
|
+
libraries = [libraries] unless libraries.is_a?(Array)
|
19
|
+
libraries.map {|e|
|
20
|
+
(@library = load_once(e, options)) ? after_load : false
|
21
|
+
}.all?
|
22
|
+
end
|
23
|
+
|
24
|
+
# Reloads a library or an array of libraries with the following options:
|
25
|
+
# * :verbose: Boolean to print reload status. Default is false.
|
26
|
+
def reload(source, options={})
|
27
|
+
if (lib = Boson.library(source))
|
28
|
+
if lib.loaded
|
29
|
+
command_size = Boson.commands.size
|
30
|
+
@options = options
|
31
|
+
if (result = rescue_load_action(lib.name, :reload) { lib.reload })
|
32
|
+
after_reload(lib)
|
33
|
+
puts "Reloaded library #{source}: Added #{Boson.commands.size - command_size} commands" if options[:verbose]
|
34
|
+
end
|
35
|
+
result
|
36
|
+
else
|
37
|
+
puts "Library hasn't been loaded yet. Loading library #{source}..." if options[:verbose]
|
38
|
+
load(source, options)
|
39
|
+
end
|
40
|
+
else
|
41
|
+
puts "Library #{source} doesn't exist." if options[:verbose]
|
42
|
+
false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
#:stopdoc:
|
47
|
+
def add_library(lib)
|
48
|
+
Boson.libraries.delete(Boson.library(lib.name))
|
49
|
+
Boson.libraries << lib
|
50
|
+
end
|
51
|
+
|
52
|
+
def loaded?(lib_name)
|
53
|
+
((lib = Boson.library(lib_name)) && lib.loaded) ? true : false
|
54
|
+
end
|
55
|
+
|
56
|
+
def rescue_load_action(library, load_method)
|
57
|
+
yield
|
58
|
+
rescue AppendFeaturesFalseError
|
59
|
+
rescue LoaderError=>e
|
60
|
+
FileLibrary.reset_file_cache(library.to_s)
|
61
|
+
print_error_message "Unable to #{load_method} library #{library}. Reason: #{e.message}"
|
62
|
+
rescue Exception=>e
|
63
|
+
FileLibrary.reset_file_cache(library.to_s)
|
64
|
+
print_error_message "Unable to #{load_method} library #{library}. Reason: #{$!}" + "\n" +
|
65
|
+
e.backtrace.slice(0,3).join("\n")
|
66
|
+
ensure
|
67
|
+
Inspector.disable if Inspector.enabled
|
68
|
+
end
|
69
|
+
|
70
|
+
def print_error_message(message)
|
71
|
+
$stderr.puts message if !@options[:index] || (@options[:index] && @options[:verbose])
|
72
|
+
end
|
73
|
+
|
74
|
+
def load_once(source, options={})
|
75
|
+
@options = options
|
76
|
+
rescue_load_action(source, :load) do
|
77
|
+
lib = loader_create(source)
|
78
|
+
if loaded?(lib.name)
|
79
|
+
$stderr.puts "Library #{lib.name} already exists" if options[:verbose] && !options[:dependency]
|
80
|
+
false
|
81
|
+
else
|
82
|
+
if lib.load { load_dependencies(lib, options) }
|
83
|
+
lib
|
84
|
+
else
|
85
|
+
$stderr.puts "Unable to load library #{lib.name}." if !options[:dependency]
|
86
|
+
false
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def lib_dependencies
|
93
|
+
@lib_dependencies ||= {}
|
94
|
+
end
|
95
|
+
|
96
|
+
def load_dependencies(lib, options={})
|
97
|
+
lib_dependencies[lib] = (lib.dependencies || []).map do |e|
|
98
|
+
next if loaded?(e)
|
99
|
+
load_once(e, options.merge(:dependency=>true)) ||
|
100
|
+
raise(LoaderError, "Can't load dependency #{e}")
|
101
|
+
end.compact
|
102
|
+
end
|
103
|
+
|
104
|
+
def loader_create(source)
|
105
|
+
lib_class = Library.handle_blocks.find {|k,v| v.call(source) } or raise(LoaderError, "Library #{source} not found.")
|
106
|
+
lib_class[0].new(:name=>source, :index=>@options[:index])
|
107
|
+
end
|
108
|
+
|
109
|
+
def after_load
|
110
|
+
create_commands(@library)
|
111
|
+
add_library(@library)
|
112
|
+
puts "Loaded library #{@library.name}" if @options[:verbose]
|
113
|
+
(lib_dependencies[@library] || []).each do |e|
|
114
|
+
create_commands(e)
|
115
|
+
add_library(e)
|
116
|
+
puts "Loaded library dependency #{e.name}" if @options[:verbose]
|
117
|
+
end
|
118
|
+
true
|
119
|
+
end
|
120
|
+
|
121
|
+
def after_reload(lib)
|
122
|
+
Boson.commands.delete_if {|e| e.lib == lib.name } if lib.new_module
|
123
|
+
create_commands(lib, lib.new_commands)
|
124
|
+
end
|
125
|
+
|
126
|
+
def before_create_commands(lib)
|
127
|
+
lib.is_a?(FileLibrary) && lib.module && Inspector.add_method_data_to_library(lib)
|
128
|
+
end
|
129
|
+
|
130
|
+
def create_commands(lib, commands=lib.commands)
|
131
|
+
if lib.except
|
132
|
+
commands -= lib.except
|
133
|
+
lib.except.each {|e| lib.namespace_object.instance_eval("class<<self;self;end").send :undef_method, e }
|
134
|
+
end
|
135
|
+
before_create_commands(lib)
|
136
|
+
commands.each {|e| Boson.commands << Command.create(e, lib)}
|
137
|
+
create_command_aliases(lib, commands) if commands.size > 0 && !lib.no_alias_creation
|
138
|
+
create_option_commands(lib, commands)
|
139
|
+
end
|
140
|
+
|
141
|
+
def create_option_commands(lib, commands)
|
142
|
+
option_commands = lib.command_objects(commands).select {|e| e.option_command? }
|
143
|
+
accepted, rejected = option_commands.partition {|e| e.args(lib) || e.arg_size }
|
144
|
+
if @options[:verbose] && rejected.size > 0
|
145
|
+
puts "Following commands cannot have options until their arguments are configured: " +
|
146
|
+
rejected.map {|e| e.name}.join(', ')
|
147
|
+
end
|
148
|
+
accepted.each {|cmd| Scientist.create_option_command(lib.namespace_object, cmd) }
|
149
|
+
end
|
150
|
+
|
151
|
+
def create_command_aliases(lib, commands)
|
152
|
+
lib.module ? prep_and_create_instance_aliases(commands, lib.module) : check_for_uncreated_aliases(lib, commands)
|
153
|
+
end
|
154
|
+
|
155
|
+
def prep_and_create_instance_aliases(commands, lib_module)
|
156
|
+
aliases_hash = {}
|
157
|
+
select_commands = Boson.commands.select {|e| commands.include?(e.name)}
|
158
|
+
select_commands.each do |e|
|
159
|
+
if e.alias
|
160
|
+
aliases_hash[lib_module.to_s] ||= {}
|
161
|
+
aliases_hash[lib_module.to_s][e.name] = e.alias
|
162
|
+
end
|
163
|
+
end
|
164
|
+
create_instance_aliases(aliases_hash)
|
165
|
+
end
|
166
|
+
|
167
|
+
def create_instance_aliases(aliases_hash)
|
168
|
+
Alias.manager.create_aliases(:instance_method, aliases_hash)
|
169
|
+
end
|
170
|
+
|
171
|
+
def create_class_aliases(mod, class_commands)
|
172
|
+
Alias.manager.create_aliases(:any_to_instance_method, mod.to_s=>class_commands.invert)
|
173
|
+
end
|
174
|
+
|
175
|
+
def check_for_uncreated_aliases(lib, commands)
|
176
|
+
return if lib.is_a?(GemLibrary)
|
177
|
+
if (found_commands = Boson.commands.select {|e| commands.include?(e.name)}) && found_commands.find {|e| e.alias }
|
178
|
+
$stderr.puts "No aliases created for library #{lib.name} because it has no module"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
#:startdoc:
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|