boson 0.4.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemspec +6 -7
- data/.rspec +2 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.rdoc +1 -1
- data/README.md +144 -0
- data/README.rdoc +2 -2
- data/Upgrading.md +23 -0
- data/bin/boson +2 -2
- data/lib/boson.rb +44 -52
- data/lib/boson/bare_runner.rb +83 -0
- data/lib/boson/bin_runner.rb +114 -0
- data/lib/boson/command.rb +92 -132
- data/lib/boson/inspector.rb +49 -48
- data/lib/boson/library.rb +71 -120
- data/lib/boson/loader.rb +73 -84
- data/lib/boson/manager.rb +131 -135
- data/lib/boson/method_inspector.rb +112 -0
- data/lib/boson/option_command.rb +71 -154
- data/lib/boson/option_parser.rb +178 -173
- data/lib/boson/options.rb +46 -32
- data/lib/boson/runner.rb +58 -66
- data/lib/boson/runner_library.rb +31 -0
- data/lib/boson/scientist.rb +48 -81
- data/lib/boson/util.rb +46 -61
- data/lib/boson/version.rb +1 -1
- data/test/bin_runner_test.rb +53 -191
- data/test/command_test.rb +5 -9
- data/test/deps.rip +2 -2
- data/test/loader_test.rb +18 -216
- data/test/manager_test.rb +69 -79
- data/test/method_inspector_test.rb +12 -36
- data/test/option_parser_test.rb +45 -32
- data/test/runner_library_test.rb +10 -0
- data/test/runner_test.rb +158 -28
- data/test/scientist_test.rb +9 -147
- data/test/test_helper.rb +87 -52
- metadata +30 -72
- data/deps.rip +0 -2
- data/lib/boson/commands.rb +0 -7
- data/lib/boson/commands/core.rb +0 -77
- data/lib/boson/commands/web_core.rb +0 -153
- data/lib/boson/index.rb +0 -48
- data/lib/boson/inspectors/argument_inspector.rb +0 -97
- data/lib/boson/inspectors/comment_inspector.rb +0 -100
- data/lib/boson/inspectors/method_inspector.rb +0 -98
- data/lib/boson/libraries/file_library.rb +0 -144
- data/lib/boson/libraries/gem_library.rb +0 -30
- data/lib/boson/libraries/local_file_library.rb +0 -30
- data/lib/boson/libraries/module_library.rb +0 -37
- data/lib/boson/libraries/require_library.rb +0 -23
- data/lib/boson/namespace.rb +0 -31
- data/lib/boson/pipe.rb +0 -147
- data/lib/boson/pipes.rb +0 -75
- data/lib/boson/repo.rb +0 -107
- data/lib/boson/runners/bin_runner.rb +0 -208
- data/lib/boson/runners/console_runner.rb +0 -58
- data/lib/boson/view.rb +0 -95
- data/test/argument_inspector_test.rb +0 -62
- data/test/commands_test.rb +0 -22
- data/test/comment_inspector_test.rb +0 -126
- data/test/file_library_test.rb +0 -42
- data/test/pipes_test.rb +0 -65
- data/test/repo_index_test.rb +0 -122
- data/test/repo_test.rb +0 -23
@@ -0,0 +1,114 @@
|
|
1
|
+
module Boson
|
2
|
+
# This class handles the boson executable.
|
3
|
+
#
|
4
|
+
# Usage for the boson shell command looks like this:
|
5
|
+
# boson [GLOBAL OPTIONS] [COMMAND] [ARGS] [COMMAND OPTIONS]
|
6
|
+
#
|
7
|
+
# The boson executable comes with several global options: :version, :execute,
|
8
|
+
# :ruby_debug, :debug, and :load_path.
|
9
|
+
class BinRunner < BareRunner
|
10
|
+
GLOBAL_OPTIONS.update(
|
11
|
+
version: {type: :boolean, desc: "Prints the current version"},
|
12
|
+
execute: {type: :string,
|
13
|
+
desc: "Executes given arguments as a one line script"},
|
14
|
+
ruby_debug: {type: :boolean, desc: "Sets $DEBUG", alias: 'D'},
|
15
|
+
debug: {type: :boolean, desc: "Prints debug info for boson"},
|
16
|
+
load_path: {type: :string, desc: "Add to front of $LOAD_PATH", alias: 'I'}
|
17
|
+
)
|
18
|
+
|
19
|
+
module API
|
20
|
+
attr_accessor :command
|
21
|
+
|
22
|
+
# Executes functionality from either an option or a command
|
23
|
+
def execute_option_or_command(options, command, args)
|
24
|
+
options[:execute] ? eval_execute_option(options[:execute]) :
|
25
|
+
execute_command(command, args)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Evaluates :execute option.
|
29
|
+
def eval_execute_option(str)
|
30
|
+
Boson.main_object.instance_eval str
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns true if an option does something and exits early
|
34
|
+
def early_option?(args)
|
35
|
+
if @options[:version]
|
36
|
+
puts("boson #{Boson::VERSION}")
|
37
|
+
true
|
38
|
+
elsif args.empty? || (@command.nil? && !@options[:execute])
|
39
|
+
print_usage
|
40
|
+
true
|
41
|
+
else
|
42
|
+
false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Determines verbosity of this class
|
47
|
+
def verbose
|
48
|
+
false
|
49
|
+
end
|
50
|
+
|
51
|
+
# Handles no method errors
|
52
|
+
def no_method_error_message(err)
|
53
|
+
@command = @command.to_s
|
54
|
+
if err.backtrace.grep(/`(invoke|full_invoke)'$/).empty? ||
|
55
|
+
!err.message[/undefined method `(\w+\.)?#{command_name(@command)}'/]
|
56
|
+
default_error_message($!)
|
57
|
+
else
|
58
|
+
command_not_found?(@command) ?
|
59
|
+
"Error: Command '#{@command}' not found" : default_error_message(err)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Determine command name given full command name. Overridden by namespaces
|
64
|
+
def command_name(cmd)
|
65
|
+
cmd
|
66
|
+
end
|
67
|
+
|
68
|
+
# Determines if a NoMethodError is a command not found error
|
69
|
+
def command_not_found?(cmd)
|
70
|
+
cmd[/\w+/]
|
71
|
+
end
|
72
|
+
|
73
|
+
# Constructs error message
|
74
|
+
def default_error_message(err)
|
75
|
+
"Error: #{err.message}"
|
76
|
+
end
|
77
|
+
|
78
|
+
def print_usage_header
|
79
|
+
puts "boson [GLOBAL OPTIONS] [COMMAND] [ARGS] [COMMAND OPTIONS]\n\n"
|
80
|
+
end
|
81
|
+
|
82
|
+
# prints full usage
|
83
|
+
def print_usage
|
84
|
+
print_usage_header
|
85
|
+
@option_parser.print_usage_table
|
86
|
+
end
|
87
|
+
end
|
88
|
+
extend API
|
89
|
+
|
90
|
+
# Starts, processes and ends a commandline request.
|
91
|
+
def self.start(args=ARGV)
|
92
|
+
super
|
93
|
+
@command, @options, @args = parse_args(args)
|
94
|
+
|
95
|
+
$:.unshift(*options[:load_path].split(":")) if options[:load_path]
|
96
|
+
Boson.debug = true if options[:debug]
|
97
|
+
$DEBUG = true if options[:ruby_debug]
|
98
|
+
return if early_option?(args)
|
99
|
+
Boson.in_shell = true
|
100
|
+
|
101
|
+
init
|
102
|
+
execute_option_or_command(@options, @command, @args)
|
103
|
+
rescue NoMethodError
|
104
|
+
abort_with no_method_error_message($!)
|
105
|
+
rescue
|
106
|
+
abort_with default_error_message($!)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Hash of global options passed in from commandline
|
110
|
+
def self.options
|
111
|
+
@options ||= {}
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
data/lib/boson/command.rb
CHANGED
@@ -1,74 +1,78 @@
|
|
1
1
|
module Boson
|
2
|
-
# A command starts with the functionality of a ruby method and adds benefits
|
2
|
+
# A command starts with the functionality of a ruby method and adds benefits
|
3
|
+
# with options, etc.
|
3
4
|
class Command
|
4
|
-
|
5
|
+
module APIClassMethods
|
6
|
+
# Creates a command given its name and a library.
|
7
|
+
def create(name, library)
|
8
|
+
new(new_attributes(name, library))
|
9
|
+
end
|
5
10
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
if @all_option_commands && !%w{get method_missing}.include?(name)
|
10
|
-
obj.make_option_command(library)
|
11
|
+
# Attributes passed to commands from its library
|
12
|
+
def library_attributes(library)
|
13
|
+
{lib: library.name}
|
11
14
|
end
|
12
|
-
obj
|
13
|
-
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
# Finds a command, aliased or not. If found returns the command object,
|
17
|
+
# otherwise returns nil.
|
18
|
+
def find(command, commands=Boson.commands)
|
19
|
+
command && commands.find {|e| [e.name, e.alias].include?(command) }
|
20
|
+
end
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
command, subcommand = command.to_s.split(NAMESPACE, 2)
|
25
|
-
commands.find {|current_command|
|
26
|
-
[current_command.name, current_command.alias].include?(subcommand) &&
|
27
|
-
current_command.library && (current_command.library.namespace == command)
|
28
|
-
}
|
29
|
-
else
|
30
|
-
commands.find {|e| [e.name, e.alias].include?(command) && !e.namespace}
|
22
|
+
# Generates a command's initial attributes when creating a command object
|
23
|
+
def new_attributes(name, library)
|
24
|
+
(library.commands_hash[name] || {}).merge(name: name).
|
25
|
+
update(library_attributes(library))
|
31
26
|
end
|
32
27
|
end
|
28
|
+
extend APIClassMethods
|
33
29
|
|
34
30
|
# One line usage for a command if it exists
|
35
31
|
def self.usage(command)
|
36
|
-
(cmd = find(command)) ? "#{command} #{cmd.usage}" :
|
32
|
+
(cmd = find(command)) ? "#{command} #{cmd.usage}" : ''
|
37
33
|
end
|
38
34
|
|
35
|
+
# Attributes that are defined as accessors
|
39
36
|
ATTRIBUTES = [:name, :lib, :alias, :desc, :options, :args, :config]
|
40
|
-
attr_accessor *(ATTRIBUTES + [:
|
41
|
-
#
|
42
|
-
|
37
|
+
attr_accessor *(ATTRIBUTES + [:default_option])
|
38
|
+
# Attributes that can be passed in at initialization
|
39
|
+
INIT_ATTRIBUTES = [:alias, :desc, :options, :default_option, :option_command]
|
40
|
+
attr_reader :file_parsed_args
|
41
|
+
|
42
|
+
# Takes a hash of attributes which map to instance variables and values.
|
43
|
+
# :name and :lib are required keys.
|
43
44
|
#
|
44
|
-
#
|
45
|
-
# [
|
46
|
-
#
|
47
|
-
# [
|
48
|
-
# [
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
# [
|
45
|
+
# @param [Hash] attributes
|
46
|
+
# @option attributes [String] :desc Description that shows up once in
|
47
|
+
# command listings
|
48
|
+
# @option attributes [String] :alias Alternative name for command
|
49
|
+
# @option attributes [Hash] :options Options passed to OptionParser
|
50
|
+
# @option attributes [Array,Integer,String] :args Should only be set if
|
51
|
+
# not automatically set. This attribute is only important for commands
|
52
|
+
# that have options. Its value can be an array, a number representing
|
53
|
+
# the number of arguments or '*' if the command has a variable number of
|
54
|
+
# arguments.
|
55
|
+
# @option attributes [String] :default_option Only for an option command
|
56
|
+
# that has one or zero arguments. This treats the given option as an optional
|
57
|
+
# first argument. Example:
|
58
|
+
# # For a command with default option 'query' and options --query and -v
|
59
|
+
# 'some -v' -> '--query=some -v'
|
60
|
+
# '-v' -> '-v'
|
61
|
+
# @option attributes [Hash] :config used by third party libraries to get and
|
62
|
+
# set custom command attributes.
|
63
|
+
# @option attributes [Boolean] :option_command Wraps a command with an
|
64
|
+
# OptionCommand object i.e. allow commands to have options.
|
61
65
|
def initialize(attributes)
|
62
66
|
hash = attributes.dup
|
63
67
|
@name = hash.delete(:name) or raise ArgumentError
|
64
68
|
@lib = hash.delete(:lib) or raise ArgumentError
|
65
|
-
|
66
|
-
|
69
|
+
# since MethodInspector scrapes arguments from file by default
|
70
|
+
@file_parsed_args = true
|
71
|
+
INIT_ATTRIBUTES.each do |e|
|
72
|
+
instance_variable_set("@#{e}", hash.delete(e)) if hash.key?(e)
|
67
73
|
end
|
68
74
|
|
69
|
-
|
70
|
-
@render_options = Util.recursive_hash_merge View.class_config(@render_options[:output_class]), @render_options
|
71
|
-
end
|
75
|
+
after_initialize(hash)
|
72
76
|
|
73
77
|
if (args = hash.delete(:args))
|
74
78
|
if args.is_a?(Array)
|
@@ -82,20 +86,34 @@ module Boson
|
|
82
86
|
@config = Util.recursive_hash_merge hash, hash.delete(:config) || {}
|
83
87
|
end
|
84
88
|
|
89
|
+
module API
|
90
|
+
# Called after initialize
|
91
|
+
def after_initialize(hash)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Alias for a name but plugins may use it to give a more descriptive name
|
95
|
+
def full_name
|
96
|
+
name
|
97
|
+
end
|
98
|
+
|
99
|
+
# One-line usage of args
|
100
|
+
def basic_usage
|
101
|
+
return '' if args.nil?
|
102
|
+
usage_args.map {|e|
|
103
|
+
(e.size < 2) ? e[0].upcase : "[#{e[0].upcase}]"
|
104
|
+
}.join(' ')
|
105
|
+
end
|
106
|
+
alias_method :usage, :basic_usage
|
107
|
+
end
|
108
|
+
include API
|
109
|
+
|
85
110
|
# Library object a command belongs to.
|
86
111
|
def library
|
87
112
|
@library ||= Boson.library(@lib)
|
88
113
|
end
|
89
114
|
|
90
|
-
# Array of array args with optional defaults. Scraped with ArgumentInspector.
|
91
115
|
def args(lib=library)
|
92
|
-
@args
|
93
|
-
if lib
|
94
|
-
file_string, meth = file_string_and_method_for_args(lib)
|
95
|
-
(file_string && meth && (@file_parsed_args = true) &&
|
96
|
-
ArgumentInspector.scrape_with_text(file_string, meth))
|
97
|
-
end || false
|
98
|
-
end
|
116
|
+
@args
|
99
117
|
end
|
100
118
|
|
101
119
|
# Option parser for command as defined by @options.
|
@@ -103,94 +121,36 @@ module Boson
|
|
103
121
|
@option_parser ||= OptionParser.new(@options || {})
|
104
122
|
end
|
105
123
|
|
106
|
-
#
|
107
|
-
def
|
108
|
-
|
109
|
-
end
|
110
|
-
|
111
|
-
# Help string for options if a command has it.
|
112
|
-
def option_help
|
113
|
-
@options ? option_parser.to_s : ''
|
114
|
-
end
|
115
|
-
|
116
|
-
# Usage string for command, created from options and args.
|
117
|
-
def usage
|
118
|
-
return '' if options.nil? && args.nil?
|
119
|
-
usage_args = args && @options && !has_splat_args? ?
|
120
|
-
(@default_option ? [[@default_option.to_s, @file_parsed_args ? ''.inspect : '']] + args[0..-2] :
|
121
|
-
args[0..-2]) : args
|
122
|
-
str = args ? usage_args.map {|e|
|
123
|
-
(e.size < 2) ? "[#{e[0]}]" : "[#{e[0]}=#{@file_parsed_args ? e[1] : e[1].inspect}]"
|
124
|
-
}.join(' ') : '[*unknown]'
|
125
|
-
str + option_help
|
126
|
-
end
|
127
|
-
|
128
|
-
# Full name is only different than name if a command has a namespace.
|
129
|
-
# The full name should be what you would type to execute the command.
|
130
|
-
def full_name
|
131
|
-
@namespace ? "#{@namespace}.#{@name}" : @name
|
124
|
+
# Indicates if an OptionCommand
|
125
|
+
def option_command?
|
126
|
+
options || @option_command
|
132
127
|
end
|
133
128
|
|
134
|
-
#:stopdoc:
|
135
129
|
# until @config is consistent in index + actual loading
|
136
130
|
def config
|
137
131
|
@config ||= {}
|
138
132
|
end
|
139
133
|
|
140
|
-
|
141
|
-
if !lib.is_a?(ModuleLibrary) && (klass_method = (lib.class_commands || {})[@name])
|
142
|
-
if RUBY_VERSION >= '1.9'
|
143
|
-
klass, meth = klass_method.split(NAMESPACE, 2)
|
144
|
-
if (meth_locations = MethodInspector.find_method_locations_for_19(klass, meth))
|
145
|
-
file_string = File.read meth_locations[0]
|
146
|
-
end
|
147
|
-
end
|
148
|
-
elsif File.exists?(lib.library_file || '')
|
149
|
-
file_string, meth = FileLibrary.read_library_file(lib.library_file), @name
|
150
|
-
end
|
151
|
-
[file_string, meth]
|
152
|
-
end
|
153
|
-
|
134
|
+
# Indicates if any arg has a splat
|
154
135
|
def has_splat_args?
|
155
136
|
!!(args && @args[-1] && @args[-1][0][/^\*/])
|
156
137
|
end
|
157
138
|
|
158
|
-
|
159
|
-
@option_command = true
|
160
|
-
@args = [['*args']] unless args(lib) || arg_size
|
161
|
-
end
|
162
|
-
|
163
|
-
def option_command?
|
164
|
-
options || render_options || @option_command
|
165
|
-
end
|
166
|
-
|
139
|
+
# Number of arguments
|
167
140
|
def arg_size
|
168
|
-
|
169
|
-
|
170
|
-
end
|
171
|
-
|
172
|
-
def file_parsed_args?
|
173
|
-
@file_parsed_args
|
174
|
-
end
|
175
|
-
|
176
|
-
# Deprecated method
|
177
|
-
def description
|
178
|
-
puts "@command.description has been changed to @command.desc. Delete your old " +
|
179
|
-
"Boson index at ~/.boson/command/index.marshal for Boson to work from the commandline."
|
180
|
-
Kernel.exit
|
181
|
-
end
|
182
|
-
|
183
|
-
def marshal_dump
|
184
|
-
if @args && @args.any? {|e| e[1].is_a?(Module) }
|
185
|
-
@args.map! {|e| e.size == 2 ? [e[0], e[1].inspect] : e }
|
186
|
-
@file_parsed_args = true
|
141
|
+
unless instance_variable_defined?("@arg_size")
|
142
|
+
@arg_size = args ? args.size : nil
|
187
143
|
end
|
188
|
-
|
144
|
+
@arg_size
|
189
145
|
end
|
190
146
|
|
191
|
-
|
192
|
-
|
147
|
+
private
|
148
|
+
def usage_args
|
149
|
+
args && @options && !has_splat_args? ?
|
150
|
+
(@default_option ?
|
151
|
+
[[@default_option.to_s, @file_parsed_args ? ''.inspect : '']] +
|
152
|
+
args[0..-2] : args[0..-2])
|
153
|
+
: args
|
193
154
|
end
|
194
|
-
#:startdoc:
|
195
155
|
end
|
196
|
-
end
|
156
|
+
end
|
data/lib/boson/inspector.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
module Boson
|
2
|
-
#
|
3
|
-
#
|
2
|
+
# Uses method decorators to scrape, process and hand off method attributes as
|
3
|
+
# data to Library objects.
|
4
4
|
#
|
5
|
-
# === Method
|
6
|
-
# Method
|
7
|
-
#
|
8
|
-
#
|
9
|
-
# # @render_options :fields=>%w{one two}
|
10
|
-
# # @config :alias=>'so'
|
5
|
+
# === Method Decorators
|
6
|
+
# Method decorators refer to methods placed before a command's method in a
|
7
|
+
# library:
|
8
|
+
# class SomeRunner < Boson::Runner
|
11
9
|
# options :verbose=>:boolean
|
12
10
|
# option :count, :numeric
|
13
11
|
# # Something descriptive perhaps
|
@@ -16,24 +14,26 @@ module Boson
|
|
16
14
|
# end
|
17
15
|
# end
|
18
16
|
#
|
19
|
-
# Method
|
20
|
-
#
|
17
|
+
# Method decorators serve as configuration for a method's command. All
|
18
|
+
# decorators should only be called once per method except for option.
|
19
|
+
# Available method decorators:
|
21
20
|
# * config: Hash to define any command attributes (see Command.new).
|
22
|
-
# * desc: String to define a command's description for a command. Defaults to
|
21
|
+
# * desc: String to define a command's description for a command. Defaults to
|
22
|
+
# first commented line above a method.
|
23
23
|
# * options: Hash to define an OptionParser object for a command's options.
|
24
|
-
# * option: Option name and value to be merged in with options. See
|
25
|
-
#
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
24
|
+
# * option: Option name and value to be merged in with options. See
|
25
|
+
# OptionParser for what an option value can be.
|
26
|
+
class Inspector
|
27
|
+
class << self; attr_reader :enabled; end
|
28
|
+
|
29
|
+
# Enable scraping by overridding method_added to snoop on a library while
|
30
|
+
# it's loading its methods.
|
31
|
+
def self.enable(options = {})
|
32
|
+
method_inspector_meth = options[:all_classes] ?
|
33
|
+
:new_method_added : :safe_new_method_added
|
34
|
+
klass = options[:module] || ::Module
|
35
|
+
@enabled = true unless options[:module]
|
32
36
|
|
33
|
-
# Enable scraping by overridding method_added to snoop on a library while it's
|
34
|
-
# loading its methods.
|
35
|
-
def enable
|
36
|
-
@enabled = true
|
37
37
|
body = MethodInspector::ALL_METHODS.map {|e|
|
38
38
|
%[def #{e}(*args)
|
39
39
|
Boson::MethodInspector.#{e}(self, *args)
|
@@ -41,17 +41,17 @@ module Boson
|
|
41
41
|
}.join("\n") +
|
42
42
|
%[
|
43
43
|
def new_method_added(method)
|
44
|
-
Boson::MethodInspector
|
44
|
+
Boson::MethodInspector.#{method_inspector_meth}(self, method)
|
45
45
|
end
|
46
46
|
|
47
47
|
alias_method :_old_method_added, :method_added
|
48
48
|
alias_method :method_added, :new_method_added
|
49
49
|
]
|
50
|
-
|
50
|
+
klass.module_eval body
|
51
51
|
end
|
52
52
|
|
53
53
|
# Disable scraping method data.
|
54
|
-
def disable
|
54
|
+
def self.disable
|
55
55
|
::Module.module_eval %[
|
56
56
|
Boson::MethodInspector::ALL_METHODS.each {|e| remove_method e }
|
57
57
|
alias_method :method_added, :_old_method_added
|
@@ -59,17 +59,27 @@ module Boson
|
|
59
59
|
@enabled = false
|
60
60
|
end
|
61
61
|
|
62
|
-
# Adds method attributes
|
63
|
-
def add_method_data_to_library(library)
|
62
|
+
# Adds method attributes to the library's commands
|
63
|
+
def self.add_method_data_to_library(library)
|
64
|
+
new(library).add_data
|
65
|
+
end
|
66
|
+
|
67
|
+
def initialize(library)
|
64
68
|
@commands_hash = library.commands_hash
|
65
69
|
@library_file = library.library_file
|
66
|
-
MethodInspector.current_module = library.module
|
67
|
-
@store = MethodInspector.store
|
68
|
-
add_method_scraped_data
|
69
|
-
add_comment_scraped_data
|
70
|
+
MethodInspector.instance.current_module = library.module
|
71
|
+
@store = MethodInspector.instance.store
|
70
72
|
end
|
71
73
|
|
72
|
-
|
74
|
+
module API
|
75
|
+
# Adds scraped data from all inspectors
|
76
|
+
def add_data
|
77
|
+
add_method_scraped_data
|
78
|
+
end
|
79
|
+
end
|
80
|
+
include API
|
81
|
+
|
82
|
+
private
|
73
83
|
def add_method_scraped_data
|
74
84
|
(MethodInspector::METHODS + [:args]).each do |key|
|
75
85
|
(@store[key] || []).each do |cmd, val|
|
@@ -83,8 +93,9 @@ module Boson
|
|
83
93
|
if valid_attr_value?(key, value)
|
84
94
|
add_scraped_data_to_config(key, value, cmd)
|
85
95
|
else
|
86
|
-
if
|
87
|
-
warn "DEBUG: Command '#{cmd}' has #{key.inspect} attribute with
|
96
|
+
if Boson.debug
|
97
|
+
warn "DEBUG: Command '#{cmd}' has #{key.inspect} attribute with " +
|
98
|
+
"invalid value '#{value.inspect}'"
|
88
99
|
end
|
89
100
|
end
|
90
101
|
end
|
@@ -94,7 +105,8 @@ module Boson
|
|
94
105
|
if key == :config
|
95
106
|
@commands_hash[cmd] = Util.recursive_hash_merge value, @commands_hash[cmd]
|
96
107
|
else
|
97
|
-
@commands_hash[cmd][key] = Util.recursive_hash_merge value,
|
108
|
+
@commands_hash[cmd][key] = Util.recursive_hash_merge value,
|
109
|
+
@commands_hash[cmd][key] || {}
|
98
110
|
end
|
99
111
|
else
|
100
112
|
@commands_hash[cmd][key] ||= value
|
@@ -105,16 +117,5 @@ module Boson
|
|
105
117
|
return true if (klass = MethodInspector::METHOD_CLASSES[key]).nil?
|
106
118
|
value.is_a?(klass) || value.nil?
|
107
119
|
end
|
108
|
-
|
109
|
-
def add_comment_scraped_data
|
110
|
-
(@store[:method_locations] || []).select {|k,(f,l)| f == @library_file }.each do |cmd, (file, lineno)|
|
111
|
-
scraped = CommentInspector.scrape(FileLibrary.read_library_file(file), lineno, MethodInspector.current_module)
|
112
|
-
@commands_hash[cmd] ||= {}
|
113
|
-
MethodInspector::METHODS.each do |e|
|
114
|
-
add_valid_data_to_config(e, scraped[e], cmd)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
#:startdoc:
|
119
120
|
end
|
120
|
-
end
|
121
|
+
end
|