acclaim 0.5.0 → 0.5.1
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/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
|