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
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
data/bin/boson
ADDED
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,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
|