boson 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/LICENSE.txt +22 -0
  2. data/README.rdoc +133 -0
  3. data/Rakefile +52 -0
  4. data/VERSION.yml +4 -0
  5. data/bin/boson +6 -0
  6. data/lib/boson.rb +72 -0
  7. data/lib/boson/command.rb +117 -0
  8. data/lib/boson/commands.rb +7 -0
  9. data/lib/boson/commands/core.rb +66 -0
  10. data/lib/boson/commands/web_core.rb +36 -0
  11. data/lib/boson/index.rb +95 -0
  12. data/lib/boson/inspector.rb +80 -0
  13. data/lib/boson/inspectors/argument_inspector.rb +92 -0
  14. data/lib/boson/inspectors/comment_inspector.rb +79 -0
  15. data/lib/boson/inspectors/method_inspector.rb +94 -0
  16. data/lib/boson/libraries/file_library.rb +76 -0
  17. data/lib/boson/libraries/gem_library.rb +21 -0
  18. data/lib/boson/libraries/module_library.rb +17 -0
  19. data/lib/boson/libraries/require_library.rb +11 -0
  20. data/lib/boson/library.rb +108 -0
  21. data/lib/boson/loader.rb +103 -0
  22. data/lib/boson/manager.rb +184 -0
  23. data/lib/boson/namespace.rb +45 -0
  24. data/lib/boson/option_parser.rb +318 -0
  25. data/lib/boson/repo.rb +38 -0
  26. data/lib/boson/runner.rb +51 -0
  27. data/lib/boson/runners/bin_runner.rb +100 -0
  28. data/lib/boson/runners/repl_runner.rb +40 -0
  29. data/lib/boson/scientist.rb +168 -0
  30. data/lib/boson/util.rb +93 -0
  31. data/lib/boson/view.rb +31 -0
  32. data/test/argument_inspector_test.rb +62 -0
  33. data/test/bin_runner_test.rb +136 -0
  34. data/test/commands_test.rb +51 -0
  35. data/test/comment_inspector_test.rb +99 -0
  36. data/test/config/index.marshal +0 -0
  37. data/test/file_library_test.rb +50 -0
  38. data/test/index_test.rb +117 -0
  39. data/test/loader_test.rb +181 -0
  40. data/test/manager_test.rb +110 -0
  41. data/test/method_inspector_test.rb +64 -0
  42. data/test/option_parser_test.rb +365 -0
  43. data/test/repo_test.rb +22 -0
  44. data/test/runner_test.rb +43 -0
  45. data/test/scientist_test.rb +291 -0
  46. data/test/test_helper.rb +119 -0
  47. metadata +133 -0
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ The MIT LICENSE
2
+
3
+ Copyright (c) 2009 Gabriel Horner
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,133 @@
1
+ == Description
2
+ A command/task framework similar to rake and thor that opens your ruby universe to the commandline
3
+ and irb. For my libraries that use this, see {irbfiles}[http://github.com/cldwalker/irbfiles].
4
+
5
+ == Features
6
+ * Commands are just methods that are extended by the toplevel object, main.
7
+ * Commands are accessible from the commandline or irb.
8
+ * Command libraries can be written as plain ruby which allows for easy testing and use outside of boson.
9
+ * Commands can be full-blown commandline apps thanks to automatic views from hirb and powerful
10
+ options similar to thor's.
11
+ * Command libraries are social as a user can install them from a url and then customize command
12
+ names and options without changing the original library.
13
+ * Namespaces are optional and when used are methods which allows for method_missing magic.
14
+
15
+ == Irb Example
16
+
17
+ To use in irb, drop this in your irbrc:
18
+ require 'boson'
19
+ Boson.start :verbose=>true
20
+
21
+ Let's start up irb:
22
+
23
+ bash> irb
24
+ Loaded library core
25
+ Loaded library web_core
26
+
27
+ # List default libraries
28
+ >> libraries
29
+ +----------+----------+------+--------------+
30
+ | name | commands | gems | library_type |
31
+ +----------+----------+------+--------------+
32
+ | core | 6 | | module |
33
+ | web_core | 3 | | module |
34
+ +----------+----------+------+--------------+
35
+ 2 rows in set
36
+
37
+ # List default commands
38
+ >> commands
39
+ +--------------+----------+-------+--------------------------------------------+-----------------------------------------------------------------------------+
40
+ | full_name | lib | alias | usage | description |
41
+ +--------------+----------+-------+--------------------------------------------+-----------------------------------------------------------------------------+
42
+ | usage | core | | [name][--verbose] | Print a command's usage |
43
+ | libraries | core | | [query=''][--index] [--query_fields=A,B,C] | List or search libraries |
44
+ | render | core | | [object] [options={}] | Render any object using Hirb |
45
+ | load_library | core | | [library][--verbose] [--reload] | Load/reload a library |
46
+ | commands | core | | [query=''][--index] [--query_fields=A,B,C] | List or search commands |
47
+ | menu | core | | [output] [options={}] [&block] | Provide a menu to multi-select elements from a given array |
48
+ | get | web_core | | [url] | Gets the body of a url |
49
+ | install | web_core | | [url][--force] [--name=NAME] | Installs a library by url. Library should then be loaded with load_library. |
50
+ | browser | web_core | | [*urls] | Opens urls in a browser |
51
+ +--------------+----------+-------+--------------------------------------------+-----------------------------------------------------------------------------+
52
+ 9 rows in set
53
+
54
+ # Boson commands can behave like shell commands:
55
+
56
+ # Basic help
57
+ >> commands '-h'
58
+ commands [query=''][--index] [--query_fields=A,B,C]
59
+
60
+ # Search the lib column for web
61
+ >> commands 'web -q=lib' # or 'web --query_fields=lib'
62
+ +-----------+----------+-------+------------------------------+-----------------------------------------------------------------------------+
63
+ | full_name | lib | alias | usage | description |
64
+ +-----------+----------+-------+------------------------------+-----------------------------------------------------------------------------+
65
+ | get | web_core | | [url] | Gets the body of a url |
66
+ | install | web_core | | [url][--force] [--name=NAME] | Installs a library by url. Library should then be loaded with load_library. |
67
+ | browser | web_core | | [*urls] | Opens urls in a browser |
68
+ +-----------+----------+-------+------------------------------+-----------------------------------------------------------------------------+
69
+ 3 rows in set
70
+
71
+ == Commandline Example
72
+
73
+ # Just like in irb
74
+ bash> boson libraries
75
+ +----------+----------+------+--------------+
76
+ | name | commands | gems | library_type |
77
+ +----------+----------+------+--------------+
78
+ | core | 6 | | module |
79
+ | web_core | 3 | | module |
80
+ +----------+----------+------+--------------+
81
+ 2 rows in set
82
+
83
+ # Let's install another library
84
+ bash> boson install http://github.com/cldwalker/irbfiles/raw/master/boson/commands/irb_core.rb
85
+ Saved to /Users/bozo/.boson/commands/irb_core.rb
86
+
87
+ # Let's start irb ...
88
+ bash> irb
89
+
90
+ >> commands
91
+ +-------------------------------+----------+------------+--------------------------------------------+-----------------------------------------------------------------------------+
92
+ | full_name | lib | alias | usage | description |
93
+ +-------------------------------+----------+------------+--------------------------------------------+-----------------------------------------------------------------------------+
94
+ | usage | core | | [name][--verbose] | Print a command's usage |
95
+ | libraries | core | | [query=''][--index] [--query_fields=name] | List or search libraries |
96
+ | render | core | | [object] [options={}] | Render any object using Hirb |
97
+ | load_library | core | | [library][--verbose] [--reload] | Load/reload a library |
98
+ | commands | core | | [query=''][--index] [--query_fields=A,B,C] | List or search commands |
99
+ | menu | core | | [output] [options={}] [&block] | Provide a menu to multi-select elements from a given array |
100
+ | get | web_core | | [url] | Gets the body of a url |
101
+ | install | web_core | | [url][--force] [--name=NAME] | Installs a library by url. Library should then be loaded with load_library. |
102
+ | browser | web_core | | [*urls] | Opens urls in a browser |
103
+ | irb_pop_workspace | irb_core | popws | | Pops current workspace and changes to next workspace in context |
104
+ | irb_require | irb_core | | | Evals file like require line by line |
105
+ | public | irb_core | | | Works same as module#public |
106
+ | private | irb_core | | | Works same as module#private |
107
+ | irb | irb_core | | | Starts a new workspace/subsession |
108
+ | irb_push_workspace | irb_core | pushws | | Creates a workspace for given object and pushes it into the current context |
109
+ | irb_load | irb_core | | | Evals file like load line by line |
110
+ | irb_change_workspace | irb_core | cws | | Changes current workspace to given object |
111
+ | irb_source | irb_core | source | | Evals full path file line by line |
112
+ | irb_jobs | irb_core | jobs | | List workspaces/subsessions |
113
+ | irb_fg | irb_core | fg | | Switch to a workspace/subsession |
114
+ | irb_help | irb_core | help | | Ri based help |
115
+ | irb_kill | irb_core | kill | | Kills a given workspace/subsession |
116
+ | include | irb_core | | | Works same as module#include |
117
+ | irb_exit | irb_core | exit | | Kills the current workspace/subsession |
118
+ | irb_workspaces | irb_core | workspaces | | Array of workspaces for current context |
119
+ | irb_context | irb_core | conf | | Displays configuration for current workspace/subsession |
120
+ | install_alias_method | irb_core | | | Aliases given method, allows lazy loading of dependent file |
121
+ | irb_current_working_workspace | irb_core | cwws | | Prints current workspace |
122
+ +-------------------------------+----------+------------+--------------------------------------------+-----------------------------------------------------------------------------+
123
+ 28 rows in set
124
+
125
+ # Sweet! Now we have a list and description of commands that come with irb.
126
+
127
+ == Creating commands
128
+ TODO: Explain library format
129
+
130
+ == Todo
131
+ * More docs
132
+ * More tests
133
+ * Add tags to libraries + commands
data/Rakefile ADDED
@@ -0,0 +1,52 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ begin
5
+ require 'rcov/rcovtask'
6
+
7
+ Rcov::RcovTask.new do |t|
8
+ t.libs << 'test'
9
+ t.test_files = FileList['test/**/*_test.rb']
10
+ t.rcov_opts = ["-T -x '/Library/Ruby/*'"]
11
+ t.verbose = true
12
+ end
13
+ rescue LoadError
14
+ puts "Rcov not available. Install it for rcov-related tasks with: sudo gem install rcov"
15
+ end
16
+
17
+ begin
18
+ require 'jeweler'
19
+ Jeweler::Tasks.new do |s|
20
+ s.name = "boson"
21
+ s.description = "A command/task framework similar to rake and thor that opens your ruby universe to the commandline and irb."
22
+ s.summary = "Although similar to rake and thor, it's focus is not on per-project tasks. Rather it provides users with the power to turn any ruby method, into a full-fledged commandline tool. Boson achieves this with powerful options (borrowed from thor) and views (thanks to hirb). Some other unique features that differentiate it from rake and thor include being accessible from irb and the commandline, being able to write boson commands in non-dsl ruby and toggling a pretty view of a command's output without additional view code."
23
+ s.email = "gabriel.horner@gmail.com"
24
+ s.homepage = "http://github.com/cldwalker/boson"
25
+ s.authors = ["Gabriel Horner"]
26
+ s.has_rdoc = true
27
+ s.rubyforge_project = 'tagaholic'
28
+ s.add_dependency 'hirb', '>= 0.2.6'
29
+ s.add_dependency 'alias', '>= 0.2.1'
30
+ s.extra_rdoc_files = ["README.rdoc", "LICENSE.txt"]
31
+ s.files = FileList["Rakefile", "VERSION.yml", "README.rdoc", "LICENSE.txt", "{bin,lib,test}/**/*"]
32
+ end
33
+
34
+ rescue LoadError
35
+ puts "Jeweler not available. Install it for jeweler-related tasks with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
36
+ end
37
+
38
+ Rake::TestTask.new do |t|
39
+ t.libs << 'lib'
40
+ t.pattern = 'test/**/*_test.rb'
41
+ t.verbose = false
42
+ end
43
+
44
+ Rake::RDocTask.new do |rdoc|
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = 'test'
47
+ rdoc.options << '--line-numbers' << '--inline-source'
48
+ rdoc.rdoc_files.include('README*')
49
+ rdoc.rdoc_files.include('lib/**/*.rb')
50
+ end
51
+
52
+ task :default => :test
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 0
4
+ :patch: 1
data/bin/boson ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__), "..","lib","boson"))
4
+ require 'boson/runners/bin_runner'
5
+
6
+ Boson::BinRunner.start
data/lib/boson.rb ADDED
@@ -0,0 +1,72 @@
1
+ $:.unshift File.dirname(__FILE__) unless $:.include? File.expand_path(File.dirname(__FILE__))
2
+ %w{hirb alias}.each {|e| require e }
3
+ %w{runner runners/repl_runner repo manager loader inspector library}.each {|e| require "boson/#{e}" }
4
+ %w{argument method comment}.each {|e| require "boson/inspectors/#{e}_inspector" }
5
+ # order of library subclasses matters
6
+ %w{module file gem require}.each {|e| require "boson/libraries/#{e}_library" }
7
+ %w{namespace view command util commands option_parser index scientist}.each {|e| require "boson/#{e}" }
8
+
9
+ # This module stores the libraries, commands, repos and main object used throughout Boson.
10
+ module Boson
11
+ # Module which is extended by Boson.main_object to give it command functionality.
12
+ module Universe; include Commands::Namespace; end
13
+ extend self
14
+ # The object which holds and executes all command functionality
15
+ attr_accessor :main_object
16
+ attr_accessor :commands, :libraries
17
+ alias_method :higgs, :main_object
18
+
19
+ # Array of loaded Boson::Library objects.
20
+ def libraries
21
+ @libraries ||= Array.new
22
+ end
23
+
24
+ # Array of loaded Boson::Command objects.
25
+ def commands
26
+ @commands ||= Array.new
27
+ end
28
+
29
+ # The main required repository which defaults to ~/.boson.
30
+ def repo
31
+ @repo ||= Repo.new("#{ENV['HOME']}/.boson")
32
+ end
33
+
34
+ # An optional local repository which defaults to ./lib/boson or ./.boson.
35
+ def local_repo
36
+ @local_repo ||= begin
37
+ dir = ["lib/boson", ".boson"].find {|e| File.directory?(e) &&
38
+ File.expand_path(e) != repo.dir }
39
+ Repo.new(dir) if dir
40
+ end
41
+ end
42
+
43
+ # The array of loaded repositories.
44
+ def repos
45
+ @repos ||= [repo, local_repo].compact
46
+ end
47
+
48
+ def main_object=(value) #:nodoc:
49
+ @main_object = value.extend(Universe)
50
+ end
51
+
52
+ def library(query, attribute='name') #:nodoc:
53
+ libraries.find {|e| e.send(attribute) == query }
54
+ end
55
+
56
+ # Start Boson by loading repositories and their configured libraries.
57
+ def start(options={})
58
+ ReplRunner.start(options)
59
+ end
60
+
61
+ # Invoke an action on the main object.
62
+ def invoke(*args, &block)
63
+ main_object.send(*args, &block)
64
+ end
65
+
66
+ # Boolean indicating if the main object can invoke the given method/command.
67
+ def can_invoke?(meth)
68
+ Boson.main_object.respond_to? meth
69
+ end
70
+ end
71
+
72
+ Boson.main_object = self
@@ -0,0 +1,117 @@
1
+ module Boson
2
+ # A command maps the functionality of a ruby method with the added benefits of options, render_options, etc.
3
+ class Command
4
+ # Creates a command given its name and a library.
5
+ def self.create(name, library)
6
+ new (library.commands_hash[name] || {}).merge({:name=>name, :lib=>library.name, :namespace=>library.namespace})
7
+ end
8
+
9
+ # Finds a command, namespaced or not and aliased or not. If found returns the
10
+ # command object, otherwise returns nil.
11
+ def self.find(command, commands=Boson.commands)
12
+ command, subcommand = command.to_s.split('.', 2)
13
+ is_namespace_command = lambda {|current_command|
14
+ [current_command.name, current_command.alias].include?(subcommand) &&
15
+ current_command.library && (current_command.library.namespace == command)
16
+ }
17
+ find_lambda = subcommand ? is_namespace_command : lambda {|e| [e.name, e.alias].include?(command)}
18
+ commands.find(&find_lambda)
19
+ end
20
+
21
+ ATTRIBUTES = [:name, :lib, :alias, :description, :options, :args]
22
+ attr_accessor *(ATTRIBUTES + [:render_options, :namespace])
23
+ # A hash of attributes which map to instance variables and values. :name
24
+ # and :lib are required keys.
25
+ def initialize(hash)
26
+ @name = hash[:name] or raise ArgumentError
27
+ @lib = hash[:lib] or raise ArgumentError
28
+ @alias = hash[:alias] if hash[:alias]
29
+ @description = hash[:description] if hash[:description]
30
+ @render_options = hash[:render_options] if hash[:render_options]
31
+ @options = hash[:options] if hash[:options]
32
+ @namespace = hash[:namespace] if hash[:namespace]
33
+ if hash[:args]
34
+ if hash[:args].is_a?(Array)
35
+ @args = hash[:args]
36
+ elsif hash[:args].to_s[/^\d+/]
37
+ @arg_size = hash[:args].to_i
38
+ elsif hash[:args] == '*'
39
+ @args = [['*args']]
40
+ end
41
+ end
42
+ end
43
+
44
+ # Library object a command belongs to.
45
+ def library
46
+ @library ||= Boson.library(@lib)
47
+ end
48
+
49
+ # Array of array args with optional defaults. Scraped with ArgumentInspector.
50
+ def args(lib=library)
51
+ @args ||= begin
52
+ if lib && File.exists?(lib.library_file || '')
53
+ @file_parsed_args = true
54
+ file_string = Boson::FileLibrary.read_library_file(lib.library_file)
55
+ ArgumentInspector.scrape_with_text(file_string, @name)
56
+ end
57
+ end
58
+ end
59
+
60
+ # Option parser for command as defined by @options.
61
+ def option_parser
62
+ @option_parser ||= (@options ? OptionParser.new(@options) : nil)
63
+ end
64
+
65
+ # Help string for options if a command has it.
66
+ def option_help
67
+ @options ? option_parser.to_s : ''
68
+ end
69
+
70
+ # Usage string for command, created from options and args.
71
+ def usage
72
+ return '' if options.nil? && args.nil?
73
+ usage_args = args && @options ? args[0..-2] : args
74
+ str = args ? usage_args.map {|e|
75
+ (e.size < 2) ? "[#{e[0]}]" : "[#{e[0]}=#{@file_parsed_args ? e[1] : e[1].inspect}]"
76
+ }.join(' ') : '[*unknown]'
77
+ str + option_help
78
+ end
79
+
80
+ # Full name is only different than name if a command has a namespace.
81
+ # The full name should be what you would type to execute the command.
82
+ def full_name
83
+ @namespace ? "#{@namespace}.#{@name}" : @name
84
+ end
85
+
86
+ #:stopdoc:
87
+ def has_splat_args?
88
+ @args && @args.any? {|e| e[0][/^\*/] }
89
+ end
90
+
91
+ def option_command?
92
+ options || render_options
93
+ end
94
+
95
+ def arg_size
96
+ @arg_size = args ? args.size : nil unless instance_variable_defined?("@arg_size")
97
+ @arg_size
98
+ end
99
+
100
+ def file_parsed_args?
101
+ @file_parsed_args
102
+ end
103
+
104
+ def marshal_dump
105
+ if @args && @args.any? {|e| e[1].is_a?(Module) }
106
+ @args.map! {|e| e.size == 2 ? [e[0], e[1].inspect] : e }
107
+ @file_parsed_args = true
108
+ end
109
+ [@name, @alias, @lib, @description, @options, @render_options, @args]
110
+ end
111
+
112
+ def marshal_load(ary)
113
+ @name, @alias, @lib, @description, @options, @render_options, @args = ary
114
+ end
115
+ #:startdoc:
116
+ end
117
+ end
@@ -0,0 +1,7 @@
1
+ # Module under which most library modules are evaluated.
2
+ module Boson::Commands
3
+ # Used for defining namespaces.
4
+ module Namespace; end
5
+ end
6
+ require 'boson/commands/core'
7
+ require 'boson/commands/web_core'
@@ -0,0 +1,66 @@
1
+ module Boson::Commands::Core #:nodoc:
2
+ def self.config
3
+ command_attributes = Boson::Command::ATTRIBUTES + [:usage, :full_name, :render_options]
4
+ library_attributes = Boson::Library::ATTRIBUTES + [:library_type]
5
+
6
+ commands = {
7
+ 'render'=>{:description=>"Render any object using Hirb"},
8
+ 'menu'=>{:description=>"Provide a menu to multi-select elements from a given array"},
9
+ 'usage'=>{:description=>"Print a command's usage", :options=>{:verbose=>:boolean}},
10
+ 'commands'=>{ :description=>"List or search commands",
11
+ :options=>{:query_fields=>{:default=>['full_name'], :values=>command_attributes},
12
+ :index=>{:type=>:boolean, :desc=>"Searches index"}},
13
+ :render_options=>{:fields=>{:default=>[:full_name, :lib, :alias, :usage, :description], :values=>command_attributes} }
14
+ },
15
+ 'libraries'=>{ :description=>"List or search libraries",
16
+ :options=>{:query_fields=>{:default=>['name'], :values=>library_attributes},
17
+ :index=>{:type=>:boolean, :desc=>"Searches index"} },
18
+ :render_options=>{
19
+ :fields=>{:default=>[:name, :commands, :gems, :library_type], :values=>library_attributes},
20
+ :filters=>{:default=>{:gems=>[:join, ','],:commands=>:size}} }
21
+ },
22
+ 'load_library'=>{:description=>"Load/reload a library", :options=>{:reload=>:boolean, :verbose=>true}}
23
+ }
24
+
25
+ {:library_file=>File.expand_path(__FILE__), :commands=>commands}
26
+ end
27
+
28
+ def commands(query='', options={})
29
+ query_fields = options[:query_fields] || ['full_name']
30
+ Boson::Index.read if options[:index]
31
+ commands = options[:index] ? Boson::Index.commands : Boson.commands
32
+ query_fields.map {|e| commands.select {|f| f.send(e).to_s =~ /#{query}/i } }.flatten
33
+ end
34
+
35
+ def libraries(query='', options={})
36
+ Boson::Index.read if options[:index]
37
+ libraries = options[:index] ? Boson::Index.libraries : Boson.libraries
38
+ options[:query_fields].map {|e| libraries.select {|f| f.send(e).to_s =~ /#{query}/i } }.flatten
39
+ end
40
+
41
+ def load_library(library, options={})
42
+ options[:reload] ? Boson::Manager.reload(library, options) :
43
+ Boson::Manager.load(library, options)
44
+ end
45
+
46
+ def render(object, options={})
47
+ Boson::View.render(object, options)
48
+ end
49
+
50
+ def menu(output, options={}, &block)
51
+ Hirb::Console.format_output(output, options.merge(:class=>"Hirb::Menu"), &block)
52
+ end
53
+
54
+ def usage(name, options={})
55
+ msg = (command = Boson::Command.find(name)) ? "#{name} #{command.usage}" : "Command '#{name}' not found"
56
+ puts msg
57
+ if command && options[:verbose]
58
+ if command.options && !command.options.empty?
59
+ puts "\nCOMMAND OPTIONS"
60
+ command.option_parser.print_usage_table
61
+ end
62
+ puts "\nGLOBAL/RENDER OPTIONS"
63
+ Boson::Scientist.render_option_parser(command).print_usage_table
64
+ end
65
+ end
66
+ end