boson-more 0.1.0
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/.gemspec +22 -0
- data/LICENSE.txt +22 -0
- data/README.md +97 -0
- data/Rakefile +35 -0
- data/deps.rip +1 -0
- data/lib/boson/alias.rb +75 -0
- data/lib/boson/argument_inspector.rb +90 -0
- data/lib/boson/commands/core.rb +67 -0
- data/lib/boson/commands/view_core.rb +19 -0
- data/lib/boson/commands/web_core.rb +153 -0
- data/lib/boson/comment_inspector.rb +100 -0
- data/lib/boson/console.rb +40 -0
- data/lib/boson/console_runner.rb +60 -0
- data/lib/boson/index.rb +48 -0
- data/lib/boson/libraries/file_library.rb +144 -0
- data/lib/boson/libraries/gem_library.rb +30 -0
- data/lib/boson/libraries/local_file_library.rb +30 -0
- data/lib/boson/libraries/module_library.rb +37 -0
- data/lib/boson/libraries/require_library.rb +23 -0
- data/lib/boson/libraries.rb +183 -0
- data/lib/boson/more/version.rb +5 -0
- data/lib/boson/more.rb +18 -0
- data/lib/boson/more_commands.rb +14 -0
- data/lib/boson/more_inspector.rb +42 -0
- data/lib/boson/more_manager.rb +34 -0
- data/lib/boson/more_method_inspector.rb +74 -0
- data/lib/boson/more_option_parser.rb +28 -0
- data/lib/boson/more_scientist.rb +68 -0
- data/lib/boson/more_util.rb +30 -0
- data/lib/boson/namespace.rb +31 -0
- data/lib/boson/namespacer.rb +117 -0
- data/lib/boson/pipe.rb +156 -0
- data/lib/boson/pipe_runner.rb +44 -0
- data/lib/boson/pipes.rb +75 -0
- data/lib/boson/repo.rb +96 -0
- data/lib/boson/repo_index.rb +135 -0
- data/lib/boson/runner_options.rb +88 -0
- data/lib/boson/save.rb +198 -0
- data/lib/boson/science.rb +273 -0
- data/lib/boson/view.rb +98 -0
- data/lib/boson/viewable.rb +48 -0
- data/test/alias_test.rb +55 -0
- data/test/argument_inspector_test.rb +40 -0
- data/test/command_test.rb +22 -0
- data/test/commands_test.rb +53 -0
- data/test/comment_inspector_test.rb +126 -0
- data/test/console_runner_test.rb +58 -0
- data/test/deps.rip +4 -0
- data/test/file_library_test.rb +41 -0
- data/test/gem_library_test.rb +40 -0
- data/test/libraries_test.rb +55 -0
- data/test/loader_test.rb +38 -0
- data/test/module_library_test.rb +30 -0
- data/test/more_manager_test.rb +29 -0
- data/test/more_method_inspector_test.rb +42 -0
- data/test/more_scientist_test.rb +10 -0
- data/test/namespacer_test.rb +61 -0
- data/test/pipes_test.rb +65 -0
- data/test/repo_index_test.rb +123 -0
- data/test/repo_test.rb +23 -0
- data/test/runner_options_test.rb +29 -0
- data/test/save_test.rb +86 -0
- data/test/science_test.rb +58 -0
- data/test/scientist_test.rb +195 -0
- data/test/test_helper.rb +165 -0
- data/test/web_test.rb +22 -0
- metadata +169 -0
@@ -0,0 +1,100 @@
|
|
1
|
+
module Boson
|
2
|
+
# Scrapes comments right before a method for its attributes. Method attributes must begin with '@' i.e.:
|
3
|
+
# # @desc Does foo
|
4
|
+
# # @options :verbose=>true
|
5
|
+
# def foo(options={})
|
6
|
+
#
|
7
|
+
# Some rules about these attributes:
|
8
|
+
# * Attribute definitions can span multiple lines. When a new attribute starts a line or the comments end,
|
9
|
+
# then a definition ends.
|
10
|
+
# * If no @desc is found in the comment block, then the first comment line directly above the method
|
11
|
+
# is assumed to be the value for @desc. This means that no multi-line attribute definitions can occur
|
12
|
+
# without a description since the last line is assumed to be a description.
|
13
|
+
# * options, option and config attributes can take any valid ruby since they're evaled in
|
14
|
+
# their module's context.
|
15
|
+
# * desc attribute is not evaled and is simply text to be set as a string.
|
16
|
+
#
|
17
|
+
# This module was inspired by
|
18
|
+
# {pragdave}[http://github.com/pragdavespc/rake/commit/45231ac094854da9f4f2ac93465ed9b9ca67b2da].
|
19
|
+
module CommentInspector
|
20
|
+
extend self
|
21
|
+
EVAL_ATTRIBUTES = [:options, :config]
|
22
|
+
|
23
|
+
# Given a method's file string, line number and defining module, returns a hash
|
24
|
+
# of attributes defined for that method.
|
25
|
+
def scrape(file_string, line, mod, attribute=nil)
|
26
|
+
hash = scrape_file(file_string, line) || {}
|
27
|
+
options = (arr = hash.delete(:option)) ? parse_option_comments(arr, mod) : {}
|
28
|
+
hash.select {|k,v| v && (attribute.nil? || attribute == k) }.each do |k,v|
|
29
|
+
hash[k] = EVAL_ATTRIBUTES.include?(k) ? eval_comment(v.join(' '), mod, k) : v.join(' ')
|
30
|
+
end
|
31
|
+
(hash[:options] ||= {}).merge!(options) if !options.empty?
|
32
|
+
attribute ? hash[attribute] : hash
|
33
|
+
end
|
34
|
+
|
35
|
+
#:stopdoc:
|
36
|
+
def parse_option_comments(arr, mod)
|
37
|
+
arr.inject({}) {|t,e|
|
38
|
+
key, val = e.join(' ').split(/\s*,\s*/, 2)
|
39
|
+
if val
|
40
|
+
key = key.sub(/^\s*:/, '').to_sym
|
41
|
+
t[key] = eval_comment(val, mod, 'option')
|
42
|
+
end
|
43
|
+
t
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def eval_comment(value, mod, mattr)
|
48
|
+
value = "{#{value}}" if !value[/^\s*\{/] && value[/=>/]
|
49
|
+
mod.module_eval(value)
|
50
|
+
rescue Exception
|
51
|
+
if Boson.debug
|
52
|
+
warn "DEBUG: Error while evaluating @#{mattr} in module #{mod.to_s[/\w+$/]}:\n " +
|
53
|
+
$!.message.gsub(/\n/, "\n ")
|
54
|
+
end
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
|
58
|
+
# Scrapes a given string for commented @keywords, starting with the line above the given line
|
59
|
+
def scrape_file(file_string, line)
|
60
|
+
lines = file_string.split("\n")
|
61
|
+
saved = []
|
62
|
+
i = line -2
|
63
|
+
while lines[i] =~ /^\s*#\s*(\S+)/ && i >= 0
|
64
|
+
saved << lines[i]
|
65
|
+
i -= 1
|
66
|
+
end
|
67
|
+
|
68
|
+
saved.empty? ? {} : splitter(saved.reverse)
|
69
|
+
end
|
70
|
+
|
71
|
+
def splitter(lines)
|
72
|
+
hash = {}
|
73
|
+
i = 0
|
74
|
+
# to magically make the last comment a description
|
75
|
+
unless lines.any? {|e| e =~ /^\s*#\s*@desc/ }
|
76
|
+
last_line = lines.pop
|
77
|
+
hash[:desc] = (last_line =~ /^\s*#\s*([^@\s].*)/) ? [$1] : nil
|
78
|
+
lines << last_line unless hash[:desc]
|
79
|
+
end
|
80
|
+
|
81
|
+
option = []
|
82
|
+
while i < lines.size
|
83
|
+
while lines[i] =~ /^\s*#\s*@(\w+)\s*(.*)/
|
84
|
+
key = $1.to_sym
|
85
|
+
hash[key] = [$2]
|
86
|
+
i += 1
|
87
|
+
while lines[i] =~ /^\s*#\s*([^@\s].*)/
|
88
|
+
hash[key] << $1
|
89
|
+
i+= 1
|
90
|
+
end
|
91
|
+
option << hash.delete(:option) if key == :option
|
92
|
+
end
|
93
|
+
i += 1
|
94
|
+
end
|
95
|
+
hash[:option] = option if !option.empty?
|
96
|
+
hash
|
97
|
+
end
|
98
|
+
#:startdoc:
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'boson/console_runner'
|
2
|
+
|
3
|
+
module Boson
|
4
|
+
CONFIG.update console_defaults: []
|
5
|
+
|
6
|
+
# Additional options added to Repo:
|
7
|
+
# [:console_defaults] Array of libraries to load at start up when used in irb. Default is to load all library files and libraries
|
8
|
+
# defined in the config.
|
9
|
+
# [:console] Console to load when using --console from commandline. Default is irb.
|
10
|
+
module Console
|
11
|
+
# Start Boson by loading repositories and their configured libraries.
|
12
|
+
# See ConsoleRunner.start for its options.
|
13
|
+
def start(options={})
|
14
|
+
ConsoleRunner.start(options)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
extend Console
|
18
|
+
|
19
|
+
# [:console] This drops Boson into irb after having loaded default commands and any explict libraries with
|
20
|
+
# :load option. This is a good way to start irb with only certain libraries loaded.
|
21
|
+
module ConsoleOptions
|
22
|
+
def early_option?(args)
|
23
|
+
if @options[:console]
|
24
|
+
ConsoleRunner.bin_start(@options[:console], @options[:load])
|
25
|
+
true
|
26
|
+
else
|
27
|
+
super
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
if defined? BinRunner
|
33
|
+
class BinRunner < BareRunner
|
34
|
+
GLOBAL_OPTIONS.update console:
|
35
|
+
{:type=>:boolean,
|
36
|
+
:desc=>"Drops into irb with default and explicit libraries loaded"}
|
37
|
+
extend ConsoleOptions
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'boson/save'
|
2
|
+
|
3
|
+
module Boson
|
4
|
+
# Runner used when starting irb. To use in irb, drop this in your ~/.irbrc:
|
5
|
+
# require 'boson'
|
6
|
+
# Boson.start
|
7
|
+
class ConsoleRunner < BareRunner
|
8
|
+
class <<self
|
9
|
+
# Starts Boson by loading configured libraries. If no default libraries are specified in the config,
|
10
|
+
# it will load up all detected libraries. Options:
|
11
|
+
# [:libraries] Array of libraries to load.
|
12
|
+
# [:verbose] Boolean to be verbose about libraries loading. Default is true.
|
13
|
+
# [:no_defaults] Boolean or :all which turns off loading default libraries. If set to true,
|
14
|
+
# effects loading user's console default libraries. If set to :all, effects
|
15
|
+
# all libraries including boson's. Default is false.
|
16
|
+
# [:autoload_libraries] Boolean which makes any command execution easier. It redefines
|
17
|
+
# method_missing on Boson.main_object so that commands with unloaded
|
18
|
+
# libraries are automatically loaded. Default is false.
|
19
|
+
def start(options={})
|
20
|
+
super
|
21
|
+
@options = {:verbose=>true}.merge options
|
22
|
+
init unless @initialized
|
23
|
+
Manager.load(@options[:libraries], load_options) if @options[:libraries]
|
24
|
+
end
|
25
|
+
|
26
|
+
# Loads libraries and then starts irb (or the configured console) from the commandline.
|
27
|
+
def bin_start(repl, libraries)
|
28
|
+
start :no_defaults=>true, :libraries=>libraries
|
29
|
+
repl = Boson.repo.config[:console] if Boson.repo.config[:console]
|
30
|
+
repl = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb' unless repl.is_a?(String)
|
31
|
+
unless repl.index('/') == 0 || (repl = Util.which(repl))
|
32
|
+
abort "Console not found. Please specify full path in config[:console]."
|
33
|
+
else
|
34
|
+
load_repl(repl)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def load_repl(repl) #:nodoc:
|
39
|
+
ARGV.replace ['-f']
|
40
|
+
$progname = $0
|
41
|
+
alias $0 $progname
|
42
|
+
Kernel.load $0 = repl
|
43
|
+
end
|
44
|
+
|
45
|
+
def init #:nodoc:
|
46
|
+
super
|
47
|
+
define_autoloader if @options[:autoload_libraries]
|
48
|
+
@initialized = true
|
49
|
+
end
|
50
|
+
|
51
|
+
def default_libraries #:nodoc:
|
52
|
+
return [] if @options[:no_defaults] == :all
|
53
|
+
return super if @options[:no_defaults]
|
54
|
+
defaults = super + Boson.repos.map {|e| e.config[:console_defaults] }.flatten
|
55
|
+
defaults += detected_libraries if defaults.empty?
|
56
|
+
defaults.uniq
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/boson/index.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Boson
|
2
|
+
# This class manages indexing/storing all commands and libraries. See RepoIndex for details
|
3
|
+
# about the index created for each Repo.
|
4
|
+
module Index
|
5
|
+
extend self
|
6
|
+
# Array of indexes, one per repo in Boson.repos.
|
7
|
+
def indexes
|
8
|
+
@indexes ||= Boson.repos.map {|e| RepoIndex.new(e) }
|
9
|
+
end
|
10
|
+
|
11
|
+
# Updates all repo indexes.
|
12
|
+
def update(options={})
|
13
|
+
indexes.each {|e| e.update(options) }
|
14
|
+
end
|
15
|
+
|
16
|
+
#:stopdoc:
|
17
|
+
def read
|
18
|
+
indexes.each {|e| e.read }
|
19
|
+
end
|
20
|
+
|
21
|
+
def find_library(command, object=false)
|
22
|
+
indexes.each {|e|
|
23
|
+
(lib = e.find_library(command, object)) and return lib
|
24
|
+
}
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def find_command(command)
|
29
|
+
indexes.each {|e|
|
30
|
+
(cmd = Command.find(command, e.commands)) and return(cmd)
|
31
|
+
}
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
|
35
|
+
def commands
|
36
|
+
indexes.map {|e| e.commands}.flatten
|
37
|
+
end
|
38
|
+
|
39
|
+
def libraries
|
40
|
+
indexes.map {|e| e.libraries}.flatten
|
41
|
+
end
|
42
|
+
|
43
|
+
def all_main_methods
|
44
|
+
indexes.map {|e| e.all_main_methods}.flatten
|
45
|
+
end
|
46
|
+
#:startdoc:
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
module Boson
|
2
|
+
# This class loads a file by its path relative to the commands directory of a repository.
|
3
|
+
# For example the library 'public/misc' could refer to the file '~/.boson/commands/public/misc.rb'.
|
4
|
+
# If a file's basename is unique in its repository, then it can be loaded with its basename i.e. 'misc'
|
5
|
+
# for the previous example. When loading a library, this class searches repositories in the order given by
|
6
|
+
# Boson.repos.
|
7
|
+
#
|
8
|
+
# === Creating a FileLibrary
|
9
|
+
# Start by creating a file with a module and some methods (See Library for naming a module).
|
10
|
+
# Non-private methods are automatically loaded as a library's commands.
|
11
|
+
#
|
12
|
+
# Take for example a library brain.rb:
|
13
|
+
# # Drop this in ~/.boson/commands/brain.rb
|
14
|
+
# module Brain
|
15
|
+
# def take_over(destination)
|
16
|
+
# puts "Pinky, it's time to take over the #{destination}!"
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# Once loaded, this library can be run from the commandline or irb:
|
21
|
+
# $ boson take_over world
|
22
|
+
# >> take_over 'world'
|
23
|
+
#
|
24
|
+
# If the library is namespaced, the command would be run as brain.take_over.
|
25
|
+
#
|
26
|
+
# Let's give Brain an option in his conquest:
|
27
|
+
# module Brain
|
28
|
+
# options :execute=>:string
|
29
|
+
# def take_over(destination, options={})
|
30
|
+
# puts "Pinky, it's time to take over the #{destination}!"
|
31
|
+
# system(options[:execute]) if options[:execute]
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# From the commandline and irb this runs as:
|
36
|
+
# $ boson take_over world -e initiate_brainiac
|
37
|
+
# >> take_over 'world -e initiate_brainiac'
|
38
|
+
#
|
39
|
+
# Since Boson aims to make your libraries just standard ruby, we can achieve the above
|
40
|
+
# by making options a commented method attribute:
|
41
|
+
# module Brain
|
42
|
+
# # @options :execute=>:string
|
43
|
+
# # Help Brain live the dream
|
44
|
+
# def take_over(destination, options={})
|
45
|
+
# puts "Pinky, it's time to take over the #{destination}!"
|
46
|
+
# system(options[:execute]) if options[:execute]
|
47
|
+
# end
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# Some points about the above:
|
51
|
+
# * A '@' must prefix options and other method attributes that become comments.
|
52
|
+
# * Note the comment above the method. One-line comments right before a method set a command's description.
|
53
|
+
# * See Inspector for other method attributes, like config that can be placed above a method.
|
54
|
+
#
|
55
|
+
# Once a command has a defined option, a command can also recognize a slew of global options:
|
56
|
+
# >> take_over '-h'
|
57
|
+
# take_over [destination] [--execute=STRING]
|
58
|
+
#
|
59
|
+
# # prints much more verbose help
|
60
|
+
# >> take_over '-hv'
|
61
|
+
#
|
62
|
+
# For more about these global options see OptionCommand and View.
|
63
|
+
class FileLibrary < Library
|
64
|
+
#:stopdoc:
|
65
|
+
def self.library_file(library, dir)
|
66
|
+
File.join(Repo.commands_dir(dir), library + ".rb")
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.matched_repo; @repo; end
|
70
|
+
|
71
|
+
def self.read_library_file(file, reload=false)
|
72
|
+
@file_cache ||= {}
|
73
|
+
@file_cache[file] = File.read(file) if (!@file_cache.has_key?(file) || reload)
|
74
|
+
@file_cache[file]
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.reset_file_cache(name=nil)
|
78
|
+
if name && @file_cache
|
79
|
+
@file_cache.delete(library_file(name, (matched_repo || Boson.repo).dir))
|
80
|
+
else
|
81
|
+
@file_cache = nil
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
handles {|source|
|
86
|
+
@repo = Boson.repos.find {|e| File.exists? library_file(source.to_s, e.dir) } ||
|
87
|
+
Boson.repos.find {|e|
|
88
|
+
Dir["#{e.commands_dir}/**/*.rb"].grep(/\/#{source}\.rb/).size == 1
|
89
|
+
}
|
90
|
+
!!@repo
|
91
|
+
}
|
92
|
+
|
93
|
+
def library_file(name=@name)
|
94
|
+
self.class.library_file(name, @repo_dir)
|
95
|
+
end
|
96
|
+
|
97
|
+
def set_repo
|
98
|
+
self.class.matched_repo
|
99
|
+
end
|
100
|
+
|
101
|
+
def set_name(name)
|
102
|
+
@lib_file = File.exists?(library_file(name.to_s)) ? library_file(name.to_s) :
|
103
|
+
Dir[self.class.matched_repo.commands_dir.to_s+'/**/*.rb'].find {|e| e =~ /\/#{name}\.rb$/}
|
104
|
+
@lib_file.gsub(/^#{self.class.matched_repo.commands_dir}\/|\.rb$/, '')
|
105
|
+
end
|
106
|
+
|
107
|
+
def base_module
|
108
|
+
@base_module ||= @name.include?('/') ? create_module_from_path : Commands
|
109
|
+
end
|
110
|
+
|
111
|
+
def load_source(reload=false)
|
112
|
+
library_string = self.class.read_library_file(@lib_file, reload)
|
113
|
+
Inspector.enable
|
114
|
+
base_module.module_eval(library_string, @lib_file)
|
115
|
+
Inspector.disable
|
116
|
+
end
|
117
|
+
|
118
|
+
def create_module_from_path(index=-2)
|
119
|
+
@name.split('/')[0..index].inject(Boson::Commands) {|base, e|
|
120
|
+
base.const_defined?(sub_mod = Util.camelize(e)) ? base.const_get(sub_mod) :
|
121
|
+
Util.create_module(base, e)
|
122
|
+
}
|
123
|
+
end
|
124
|
+
|
125
|
+
def load_source_and_set_module
|
126
|
+
detected = detect_additions(:modules=>true) { load_source }
|
127
|
+
@module = determine_lib_module(detected[:modules]) unless @module
|
128
|
+
end
|
129
|
+
|
130
|
+
def determine_lib_module(detected_modules)
|
131
|
+
detected_modules = detected_modules.select {|e| e.to_s[/^#{base_module}::/] }
|
132
|
+
case detected_modules.size
|
133
|
+
when 1 then lib_module = detected_modules[0]
|
134
|
+
when 0 then lib_module = create_module_from_path(-1)
|
135
|
+
else
|
136
|
+
unless (lib_module = Util.constantize("boson/commands/#{@name}")) && lib_module.to_s[/^Boson::Commands/]
|
137
|
+
raise LoaderError, "Can't detect module. Specify a module in this library's config."
|
138
|
+
end
|
139
|
+
end
|
140
|
+
lib_module
|
141
|
+
end
|
142
|
+
#:startdoc:
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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
|
+
#
|
5
|
+
# Example:
|
6
|
+
# >> load_library 'httparty', :class_commands=>{'put'=>'HTTParty.put',
|
7
|
+
# 'delete'=>'HTTParty.delete' }
|
8
|
+
# => true
|
9
|
+
# >> put 'http://someurl.com'
|
10
|
+
class GemLibrary < Library
|
11
|
+
#:stopdoc:
|
12
|
+
def self.is_a_gem?(name)
|
13
|
+
return false unless defined? Gem
|
14
|
+
Gem::VERSION >= '1.8.0' ?
|
15
|
+
Gem::Specification.find_all_by_name(name)[0].is_a?(Gem::Specification) :
|
16
|
+
Gem.searcher.find(name).is_a?(Gem::Specification)
|
17
|
+
end
|
18
|
+
|
19
|
+
handles {|source| is_a_gem?(source.to_s) }
|
20
|
+
|
21
|
+
def loaded_correctly?
|
22
|
+
!@gems.empty? || !@commands.empty? || !!@module
|
23
|
+
end
|
24
|
+
|
25
|
+
def load_source_and_set_module
|
26
|
+
detect_additions { Util.safe_require @name }
|
27
|
+
end
|
28
|
+
#:startdoc:
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# This class loads any local file and is most commonly used to load a local
|
2
|
+
# Bosonfile. Since this file doesn't exist inside a normal Repo, it is not indexed with any repo.
|
3
|
+
# Since file-based libraries need to be associated with a repository, Boson associates it
|
4
|
+
# with a local repository if it exists or defaults to Boson.repo. See Boson::FileLibrary
|
5
|
+
# for more info about this library.
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
# >> load_library 'Bosonfile'
|
9
|
+
# => true
|
10
|
+
class Boson::LocalFileLibrary < Boson::FileLibrary
|
11
|
+
handles {|source|
|
12
|
+
@repo = (File.exists?(source.to_s) ? (Boson.local_repo || Boson.repo) : nil)
|
13
|
+
!!@repo
|
14
|
+
}
|
15
|
+
|
16
|
+
#:stopdoc:
|
17
|
+
def set_name(name)
|
18
|
+
@lib_file = File.expand_path(name.to_s)
|
19
|
+
File.basename(@lib_file).downcase
|
20
|
+
end
|
21
|
+
|
22
|
+
def base_module
|
23
|
+
Boson::Commands
|
24
|
+
end
|
25
|
+
|
26
|
+
def library_file
|
27
|
+
@lib_file
|
28
|
+
end
|
29
|
+
#:startdoc:
|
30
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Boson
|
2
|
+
# This library takes a module or class as a library's name and loads its class methods
|
3
|
+
# as commands. If no commands are given it defaults to loading all of its class methods
|
4
|
+
# as commands. The only method callback (see Loader) this library calls on the
|
5
|
+
# original module/class is config().
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
# >> load_library Math, :commands=>%w{sin cos tan}
|
9
|
+
# => true
|
10
|
+
#
|
11
|
+
# # Let's brush up on ol trig
|
12
|
+
# >> sin (Math::PI/2)
|
13
|
+
# => 1.0
|
14
|
+
# >> tan (Math::PI/4)
|
15
|
+
# => 1.0
|
16
|
+
# # Close enough :)
|
17
|
+
# >> cos (Math::PI/2)
|
18
|
+
# => 6.12323399573677e-17
|
19
|
+
|
20
|
+
class ModuleLibrary < Library
|
21
|
+
#:stopdoc:
|
22
|
+
handles {|source| source.is_a?(Module) }
|
23
|
+
|
24
|
+
def set_name(name)
|
25
|
+
@module = name
|
26
|
+
underscore_lib = name.to_s[/^Boson::Commands/] ? name.to_s.split('::')[-1] : name.to_s
|
27
|
+
Util.underscore(underscore_lib)
|
28
|
+
end
|
29
|
+
|
30
|
+
def load_commands
|
31
|
+
@class_commands = {@module.to_s=>Array(@commands).empty? ? @module.methods(false) : @commands }
|
32
|
+
@module = nil
|
33
|
+
super
|
34
|
+
end
|
35
|
+
#:startdoc:
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,23 @@
|
|
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
|
+
#
|
4
|
+
# Example:
|
5
|
+
# >> load_library 'fileutils', :class_commands=>{'cd'=>'FileUtils.cd', 'cp'=>'FileUtils.cp'}
|
6
|
+
# => true
|
7
|
+
# >> cd '/home'
|
8
|
+
# => 0
|
9
|
+
# >> Dir.pwd
|
10
|
+
# >> '/home'
|
11
|
+
class Boson::RequireLibrary < Boson::GemLibrary
|
12
|
+
EXTENSIONS = ['', '.rb', '.rbw', '.so', '.bundle', '.dll', '.sl', '.jar']
|
13
|
+
handles {|source|
|
14
|
+
extensions_glob = "{#{EXTENSIONS.join(',')}}"
|
15
|
+
($LOAD_PATH - ['.']).any? {|dir|
|
16
|
+
Dir["#{File.expand_path source.to_s, dir}#{extensions_glob}"].size > 0
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
def loaded_correctly?
|
21
|
+
super || $".grep(/^#{@name}\.([a-z]+)?$/).size > 0
|
22
|
+
end
|
23
|
+
end
|