acclaim 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/acclaim.version +1 -1
- data/lib/acclaim/command.rb +0 -7
- data/lib/acclaim/command/dsl.rb +77 -34
- data/lib/acclaim/option/arity.rb +52 -25
- data/lib/acclaim/option/type.rb +27 -15
- data/lib/acclaim/option/type/big_decimal.rb +3 -0
- data/lib/acclaim/option/type/complex.rb +3 -0
- data/lib/acclaim/option/type/date.rb +2 -0
- data/lib/acclaim/option/type/date_time.rb +2 -0
- data/lib/acclaim/option/type/float.rb +3 -0
- data/lib/acclaim/option/type/integer.rb +3 -0
- data/lib/acclaim/option/type/pathname.rb +3 -0
- data/lib/acclaim/option/type/rational.rb +3 -0
- data/lib/acclaim/option/type/string.rb +2 -0
- data/lib/acclaim/option/type/symbol.rb +3 -0
- data/lib/acclaim/option/type/time.rb +2 -0
- data/lib/acclaim/option/type/uri.rb +2 -0
- metadata +4 -4
data/acclaim.version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.1
|
data/lib/acclaim/command.rb
CHANGED
data/lib/acclaim/command/dsl.rb
CHANGED
@@ -1,4 +1,15 @@
|
|
1
|
-
|
1
|
+
%w(
|
2
|
+
|
3
|
+
acclaim/command/dsl/root
|
4
|
+
acclaim/command/parser
|
5
|
+
acclaim/option
|
6
|
+
acclaim/option/parser
|
7
|
+
acclaim/option/parser/regexp
|
8
|
+
|
9
|
+
ribbon
|
10
|
+
ribbon/core_extensions/object
|
11
|
+
|
12
|
+
).each { |file| require file }
|
2
13
|
|
3
14
|
module Acclaim
|
4
15
|
class Command
|
@@ -29,14 +40,14 @@ module Acclaim
|
|
29
40
|
|
30
41
|
# Commands which may be given to this command.
|
31
42
|
#
|
32
|
-
# @return [Array] this command's subcommands
|
43
|
+
# @return [Array<Acclaim::Command::DSL>] this command's subcommands
|
33
44
|
def subcommands
|
34
45
|
@subcommands ||= []
|
35
46
|
end
|
36
47
|
|
37
48
|
# The options this command can take.
|
38
49
|
#
|
39
|
-
# @return [Array] the options this command takes
|
50
|
+
# @return [Array<Acclaim::Option>] the options this command takes
|
40
51
|
def options
|
41
52
|
@options ||= []
|
42
53
|
end
|
@@ -54,8 +65,8 @@ module Acclaim
|
|
54
65
|
#
|
55
66
|
# @yieldparam [Ribbon] options a Ribbon instance which associates options
|
56
67
|
# with their corresponding values
|
57
|
-
# @yieldparam [Array] arguments the arguments that remained in the
|
58
|
-
# line
|
68
|
+
# @yieldparam [Array<String>] arguments the arguments that remained in the
|
69
|
+
# command line
|
59
70
|
# @return [Proc, nil] the given block
|
60
71
|
def action(&block)
|
61
72
|
@action = block if block.respond_to? :call
|
@@ -64,74 +75,106 @@ module Acclaim
|
|
64
75
|
|
65
76
|
alias when_called action
|
66
77
|
|
67
|
-
# Parses the
|
78
|
+
# Parses the given arguments using this command's set of options.
|
79
|
+
#
|
80
|
+
# @param [Array<String>] arguments the argument array
|
81
|
+
# @return [Ribbon::Wrapper] ribbon containing the values
|
68
82
|
def parse_options_in!(arguments)
|
69
83
|
Option::Parser.new(arguments, options).parse!
|
70
84
|
end
|
71
85
|
|
72
|
-
#
|
86
|
+
# Searches the given arguments for one of this command's subcommands.
|
87
|
+
#
|
88
|
+
# @param [Array<String>] arguments the argument array
|
89
|
+
# @return [Acclaim::Command::DSL, nil] a subcommand of this command or nil
|
90
|
+
# if there was no match
|
73
91
|
def parse_subcommands_in!(arguments)
|
74
92
|
Command::Parser.new(arguments, subcommands).parse!
|
75
93
|
end
|
76
94
|
|
77
|
-
# Invokes this command with
|
95
|
+
# Invokes this command with the given arguments. Outputs
|
96
|
+
# {Option::Parser::Error parser error} messages to the standard error
|
97
|
+
# stream.
|
98
|
+
#
|
99
|
+
# @param [Array<String>] arguments the argument array
|
100
|
+
# @see #invoke
|
78
101
|
def run(*arguments)
|
79
102
|
invoke arguments
|
80
103
|
rescue Option::Parser::Error => error
|
81
104
|
$stderr.puts error.message
|
82
105
|
end
|
83
106
|
|
84
|
-
#
|
85
|
-
#
|
86
|
-
# will be executed. A subcommand may be anywhere in the array as long as
|
87
|
-
# it is before an argument separator, which is tipically a double dash
|
88
|
-
# (<tt>--</tt>) and may be omitted.
|
107
|
+
# Searches the given arguments for subcommands and {#invoke invokes} it.
|
108
|
+
# If none were found, {#execute executes} this command instead.
|
89
109
|
#
|
90
|
-
#
|
91
|
-
# command
|
92
|
-
|
93
|
-
|
110
|
+
# The arguments will be parsed using all options from {#command_ancestors
|
111
|
+
# this command and its parents}.
|
112
|
+
#
|
113
|
+
# @note Argument separators will be deleted prior to command execution.
|
114
|
+
#
|
115
|
+
# @param [Array<String>] arguments the argument array
|
116
|
+
def invoke(arguments = [])
|
94
117
|
subcommand = parse_subcommands_in! arguments
|
95
118
|
if subcommand.nil?
|
96
|
-
|
119
|
+
all_options = command_ancestors.collect(&:options).flatten
|
120
|
+
parsed_options = Option::Parser.new(arguments, all_options).parse!
|
97
121
|
delete_argument_separators_in! arguments
|
98
122
|
execute parsed_options, arguments
|
99
123
|
else
|
100
|
-
subcommand.invoke arguments
|
124
|
+
subcommand.invoke arguments
|
101
125
|
end
|
102
126
|
end
|
103
127
|
|
104
|
-
# Calls this command's action block with the given option values
|
105
|
-
# arguments.
|
106
|
-
|
107
|
-
|
128
|
+
# Calls this command's {#action action block} with the given option values
|
129
|
+
# and arguments.
|
130
|
+
#
|
131
|
+
# @param [Ribbon::Wrapper] options ribbon containing options and values
|
132
|
+
# @param [Array<String>] arguments additional arguments to the program
|
133
|
+
def execute(options, arguments = [])
|
134
|
+
action.instance_eval do
|
135
|
+
call options, arguments if respond_to? :call
|
136
|
+
end
|
108
137
|
end
|
109
138
|
|
110
139
|
alias call execute
|
111
140
|
|
112
|
-
# True if this is a top-level command.
|
113
|
-
def root?
|
114
|
-
superclass == Acclaim::Command
|
115
|
-
end
|
116
|
-
|
117
141
|
# Returns all command ancestors of this command.
|
142
|
+
#
|
143
|
+
# @return [Array<Acclaim::Command::DSL] this command's parent commands
|
118
144
|
def command_ancestors
|
119
145
|
ancestors - Acclaim::Command.ancestors
|
120
146
|
end
|
121
147
|
|
122
148
|
# Returns the root of the command hierarchy.
|
149
|
+
#
|
150
|
+
# @return [Acclaim::Command::DSL] the top-level command
|
123
151
|
def root
|
124
152
|
command_ancestors.last
|
125
153
|
end
|
126
154
|
|
155
|
+
# Whether this is a top-level command.
|
156
|
+
#
|
157
|
+
# @return [true, false] whether this command is at the root of the
|
158
|
+
# hierarchy
|
159
|
+
def root?
|
160
|
+
self == root
|
161
|
+
end
|
162
|
+
|
127
163
|
# Returns the sequence of commands from #root that leads to this command.
|
164
|
+
#
|
165
|
+
# @return [Array<Acclaim::Command::DSL>] the path to this command
|
128
166
|
def command_path
|
129
167
|
command_ancestors.reverse
|
130
168
|
end
|
131
169
|
|
132
|
-
# Computes the full command line of this command,
|
133
|
-
#
|
170
|
+
# Computes the full command line of this command, taking parent commands
|
171
|
+
# into account.
|
172
|
+
#
|
173
|
+
# @param [Hash, Ribbon, Ribbon::Wrapper] options method options
|
174
|
+
# @option options [true, false] :include_root (false) whether to include
|
175
|
+
# the {#root root} command in the full command line
|
134
176
|
#
|
177
|
+
# @example
|
135
178
|
# class Command < Acclaim::Command
|
136
179
|
# class Do < Command
|
137
180
|
# class Something < Do
|
@@ -140,12 +183,12 @@ module Acclaim
|
|
140
183
|
# end
|
141
184
|
#
|
142
185
|
# Command::Do::Something.full_line
|
143
|
-
#
|
186
|
+
# # => "do something"
|
144
187
|
#
|
145
188
|
# Command::Do::Something.full_line include_root: true
|
146
|
-
#
|
147
|
-
def full_line(
|
148
|
-
options =
|
189
|
+
# # => "command do something"
|
190
|
+
def full_line(options = {})
|
191
|
+
options = Ribbon.wrap options
|
149
192
|
command_path.tap do |path|
|
150
193
|
path.shift unless options.include_root?
|
151
194
|
end.map(&:line).join ' '
|
data/lib/acclaim/option/arity.rb
CHANGED
@@ -5,6 +5,9 @@ module Acclaim
|
|
5
5
|
|
6
6
|
# Represents the the number of arguments an option can take, both mandatory
|
7
7
|
# and optional.
|
8
|
+
#
|
9
|
+
# @author Matheus Afonso Martins Moreira
|
10
|
+
# @since 0.0.2
|
8
11
|
class Arity
|
9
12
|
|
10
13
|
# The minimum number of arguments.
|
@@ -13,58 +16,78 @@ module Acclaim
|
|
13
16
|
# The number of optional arguments.
|
14
17
|
attr_accessor :optional
|
15
18
|
|
16
|
-
# Same as +minimum+.
|
17
19
|
alias required minimum
|
18
20
|
|
19
|
-
# Initializes
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
21
|
+
# Initializes an arity with the given number of required and optional
|
22
|
+
# parameters. If the latter is less than zero, then it means the option
|
23
|
+
# may take infinite parameters, as long as it takes the minimum number of
|
24
|
+
# parameters.
|
25
|
+
#
|
26
|
+
# @param [Integer] minimum the number of mandatory parameters
|
27
|
+
# @param [Integer] optional the number of optional parameters
|
23
28
|
def initialize(minimum = 0, optional = 0)
|
24
29
|
@minimum, @optional = minimum, optional
|
25
30
|
end
|
26
31
|
|
27
|
-
#
|
32
|
+
# Whether the option takes +n+ and only +n+ parameters.
|
33
|
+
#
|
34
|
+
# @param [Integer] n the number of parameters
|
35
|
+
# @return [true, false] whether the option takes only +n+ parameters
|
28
36
|
def only?(n)
|
29
37
|
optional.zero? and minimum == n
|
30
38
|
end
|
31
39
|
|
32
|
-
#
|
33
|
-
|
40
|
+
# Whether the option takes no parameters.
|
41
|
+
#
|
42
|
+
# @return [true, false] whether the option takes zero parameters
|
43
|
+
# @since 0.5.1
|
44
|
+
def zero?
|
34
45
|
only? 0
|
35
46
|
end
|
36
47
|
|
37
|
-
|
48
|
+
alias none? zero?
|
49
|
+
|
50
|
+
# Whether the option can take an unlimited number of arguments.
|
51
|
+
#
|
52
|
+
# @return [true, false] whether the option can take infinite parameters
|
38
53
|
def unlimited?
|
39
54
|
optional < 0
|
40
55
|
end
|
41
56
|
|
42
|
-
#
|
57
|
+
# Whether the option must take a finite number of arguments.
|
58
|
+
#
|
59
|
+
# @return [true, false] whether the maximum number of arguments is limited
|
60
|
+
# @see #total
|
43
61
|
def bound?
|
44
62
|
not unlimited?
|
45
63
|
end
|
46
64
|
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
# parameters
|
65
|
+
# The total number of parameters that the option may take, or +nil+ if the
|
66
|
+
# option can take an infinite number of arguments.
|
67
|
+
#
|
68
|
+
# @return [Integer, nil] the total number of parameters or nil if infinite
|
51
69
|
def total
|
52
|
-
bound?
|
70
|
+
if bound? then minimum + optional else nil end
|
53
71
|
end
|
54
72
|
|
55
|
-
# Converts this arity to an array in the form of
|
56
|
-
#
|
73
|
+
# Converts this arity to an array in the form of:
|
74
|
+
#
|
75
|
+
# [ required, optional ]
|
76
|
+
#
|
77
|
+
# @return [Array<Integer>] number of required and optional parameters in
|
78
|
+
# order
|
57
79
|
def to_a
|
58
80
|
[ minimum, optional ]
|
59
81
|
end
|
60
82
|
|
61
|
-
# Same as +to_a+.
|
62
83
|
alias to_ary to_a
|
63
|
-
|
64
|
-
# Same as +to_a+.
|
65
84
|
alias to_array to_a
|
66
85
|
|
67
|
-
# Equivalent to
|
86
|
+
# Equivalent to:
|
87
|
+
#
|
88
|
+
# to_a.hash
|
89
|
+
#
|
90
|
+
# @return [Integer] hash value for this arity
|
68
91
|
def hash
|
69
92
|
to_a.hash
|
70
93
|
end
|
@@ -78,12 +101,16 @@ module Acclaim
|
|
78
101
|
to_a == arity.to_a
|
79
102
|
end
|
80
103
|
|
81
|
-
# Same as <tt>==</tt>
|
82
|
-
alias eql? ==
|
83
|
-
|
84
|
-
# Same as <tt>==</tt>
|
85
104
|
alias === ==
|
86
105
|
|
106
|
+
# Same as {#== ==} but does not compare directly with arrays.
|
107
|
+
#
|
108
|
+
# @param [Arity] arity the arity to compare this instance to
|
109
|
+
# @return [true, false] whether this instance is equal to the given arity
|
110
|
+
def eql?(arity)
|
111
|
+
minimum == arity.minimum and optional == arity.optional
|
112
|
+
end
|
113
|
+
|
87
114
|
# Returns a string in the following format:
|
88
115
|
#
|
89
116
|
# minimum +optional
|
data/lib/acclaim/option/type.rb
CHANGED
@@ -2,6 +2,9 @@ module Acclaim
|
|
2
2
|
class Option
|
3
3
|
|
4
4
|
# Associates a class with a handler block.
|
5
|
+
#
|
6
|
+
# @author Matheus Afonso Martins Moreira
|
7
|
+
# @since 0.0.4
|
5
8
|
module Type
|
6
9
|
end
|
7
10
|
|
@@ -10,6 +13,9 @@ module Acclaim
|
|
10
13
|
|
11
14
|
# Yields class, proc pairs if a block was given. Returns an enumerator
|
12
15
|
# otherwise.
|
16
|
+
#
|
17
|
+
# @yieldparam [Class, Module] type the class or module
|
18
|
+
# @yieldparam [Proc] handler the type handler
|
13
19
|
def each(&block)
|
14
20
|
table.each &block
|
15
21
|
end
|
@@ -18,37 +24,43 @@ module Acclaim
|
|
18
24
|
include Enumerable
|
19
25
|
|
20
26
|
# Returns all registered classes.
|
27
|
+
#
|
28
|
+
# @return [Array<Class, Module>] registered types
|
21
29
|
def all
|
22
30
|
table.keys
|
23
31
|
end
|
24
32
|
|
33
|
+
alias registered all
|
34
|
+
|
25
35
|
# Registers a handler for a class.
|
26
|
-
|
27
|
-
|
36
|
+
#
|
37
|
+
# @param [Class, Module] types the types to associate with the handler
|
38
|
+
# @param [Proc] block the type handler
|
39
|
+
# @yieldparam [String] string the command line argument
|
40
|
+
# @yieldreturn [Class, Module] new object of the handled type
|
41
|
+
def register(*types, &block)
|
42
|
+
types.each { |type| table[type] = block }
|
28
43
|
end
|
29
44
|
|
45
|
+
alias add_handler_for register
|
46
|
+
alias accept register
|
47
|
+
|
30
48
|
# Returns the handler for the given class.
|
31
|
-
|
32
|
-
|
33
|
-
|
49
|
+
#
|
50
|
+
# @param [Class, Module] type the handler associated with the given type
|
51
|
+
def handler_for(type)
|
52
|
+
table.fetch type do
|
53
|
+
raise "#{type} does not have an associated handler"
|
34
54
|
end
|
35
55
|
end
|
36
56
|
|
37
|
-
# Same as <tt>all</tt>.
|
38
|
-
alias registered all
|
39
|
-
|
40
|
-
# Same as <tt>register</tt>.
|
41
|
-
alias add_handler_for register
|
42
|
-
|
43
|
-
# Same as <tt>register</tt>.
|
44
|
-
alias accept register
|
45
|
-
|
46
|
-
# Same as <tt>handler_for</tt>.
|
47
57
|
alias [] handler_for
|
48
58
|
|
49
59
|
private
|
50
60
|
|
51
61
|
# The hash used to associate classes with their handlers.
|
62
|
+
#
|
63
|
+
# @return [Hash] the type handler table
|
52
64
|
def table
|
53
65
|
@table ||= {}
|
54
66
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acclaim
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06-
|
12
|
+
date: 2012-06-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: jewel
|
@@ -172,7 +172,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
172
172
|
version: '0'
|
173
173
|
segments:
|
174
174
|
- 0
|
175
|
-
hash:
|
175
|
+
hash: 4151957857271700799
|
176
176
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
177
177
|
none: false
|
178
178
|
requirements:
|
@@ -181,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
181
181
|
version: '0'
|
182
182
|
segments:
|
183
183
|
- 0
|
184
|
-
hash:
|
184
|
+
hash: 4151957857271700799
|
185
185
|
requirements: []
|
186
186
|
rubyforge_project:
|
187
187
|
rubygems_version: 1.8.24
|