boson 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|