acclaim 0.1.0 → 0.2.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/README.markdown +11 -1
- data/lib/acclaim/command.rb +45 -5
- data/lib/acclaim/command/help.rb +58 -37
- data/lib/acclaim/command/help/template.rb +32 -13
- data/lib/acclaim/command/help/template/command.erb +3 -2
- data/lib/acclaim/command/version.rb +41 -31
- data/lib/acclaim/option/parser.rb +14 -14
- data/lib/acclaim/option/parser/regexp.rb +7 -6
- data/lib/acclaim/version.rb +1 -1
- data/spec/acclaim/option/parser/regexp_spec.rb +238 -0
- data/spec/acclaim/option/parser_spec.rb +3 -3
- data/spec/acclaim/option_spec.rb +4 -4
- metadata +11 -10
data/README.markdown
CHANGED
@@ -2,7 +2,17 @@
|
|
2
2
|
|
3
3
|
Command-line option parsing and command interface.
|
4
4
|
|
5
|
-
|
5
|
+
# Installation
|
6
|
+
|
7
|
+
Latest version:
|
8
|
+
|
9
|
+
gem install acclaim
|
10
|
+
|
11
|
+
From source:
|
12
|
+
|
13
|
+
git clone git://github.com/matheusmoreira/acclaim.git
|
14
|
+
|
15
|
+
# Introduction
|
6
16
|
|
7
17
|
Acclaim makes it easy to describe commands and options for a command-line
|
8
18
|
application in a structured manner. Commands are classes that inherit from
|
data/lib/acclaim/command.rb
CHANGED
@@ -83,13 +83,13 @@ module Acclaim
|
|
83
83
|
alias :when_called :action
|
84
84
|
|
85
85
|
# Adds help subcommand and options to this command.
|
86
|
-
def help(
|
87
|
-
Help.create(self,
|
86
|
+
def help(*args)
|
87
|
+
Help.create(self, *args)
|
88
88
|
end
|
89
89
|
|
90
90
|
# Adds help subcommand and options to this command.
|
91
|
-
def version(
|
92
|
-
Version.create(self,
|
91
|
+
def version(*args)
|
92
|
+
Version.create(self, *args)
|
93
93
|
end
|
94
94
|
|
95
95
|
# Parses the argument array using this command's set of options.
|
@@ -145,16 +145,56 @@ module Acclaim
|
|
145
145
|
# Finds the root of the command hierarchy.
|
146
146
|
def root
|
147
147
|
command = self
|
148
|
-
|
148
|
+
until command.root?
|
149
|
+
yield command if block_given?
|
150
|
+
command = command.superclass
|
151
|
+
end
|
152
|
+
yield command if block_given?
|
149
153
|
command
|
150
154
|
end
|
151
155
|
|
156
|
+
# Walks the command inheritance tree, yielding each command successively
|
157
|
+
# until the root command.
|
158
|
+
alias until_root root
|
159
|
+
|
160
|
+
# Return this command's parent commands.
|
161
|
+
def parents
|
162
|
+
Array.new.tap do |parents|
|
163
|
+
until_root do |command|
|
164
|
+
parents << command
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# Computes the full command line of this command, which takes parent
|
170
|
+
# commands into account.
|
171
|
+
#
|
172
|
+
# class Command < Acclaim::Command
|
173
|
+
# class Subcommand < Command
|
174
|
+
# class Subcommand2 < Subcommand
|
175
|
+
# end
|
176
|
+
# end
|
177
|
+
# end
|
178
|
+
#
|
179
|
+
# Command::Subcommand::Subcommand2.full_line
|
180
|
+
# => "subcommand subcommand2"
|
181
|
+
#
|
182
|
+
# Command::Subcommand::Subcommand2.full_line include_root: true
|
183
|
+
# => "command subcommand subcommand2"
|
184
|
+
def full_line(*args)
|
185
|
+
options = args.extract_ribbon!
|
186
|
+
parents.tap do |parents|
|
187
|
+
parents.pop unless options.include_root?
|
188
|
+
end.reverse.map(&:line).join ' '
|
189
|
+
end
|
190
|
+
|
152
191
|
private
|
153
192
|
|
154
193
|
# Handles special options such as <tt>--help</tt> or <tt>--version</tt>.
|
155
194
|
def handle_special_options!(opts, args)
|
156
195
|
const_get(:Help).execute opts, args if opts.acclaim_help?
|
157
196
|
const_get(:Version).execute opts, args if opts.acclaim_version?
|
197
|
+
# TODO: possibly rescue a NameError and warn user
|
158
198
|
end
|
159
199
|
|
160
200
|
# Deletes all argument separators in the given argument array.
|
data/lib/acclaim/command/help.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'acclaim/command/help/template'
|
2
|
+
require 'ribbon/core_ext/array'
|
2
3
|
|
3
4
|
module Acclaim
|
4
5
|
class Command
|
@@ -6,47 +7,67 @@ module Acclaim
|
|
6
7
|
# Module which adds help support to a command.
|
7
8
|
module Help
|
8
9
|
|
9
|
-
#
|
10
|
-
|
11
|
-
# The last argument is an option +Hash+, which accepts the following
|
12
|
-
# options:
|
13
|
-
#
|
14
|
-
# [:switches] The switches used when creating the help option.
|
15
|
-
def self.add_options_to!(command, opts = {})
|
16
|
-
switches = opts.fetch :switches, %w(-h --help)
|
17
|
-
description = opts.fetch :description, 'Show usage information and exit.'
|
18
|
-
command.option :acclaim_help, *switches, description
|
19
|
-
end
|
10
|
+
# The class methods.
|
11
|
+
class << self
|
20
12
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
13
|
+
# Creates a help subcommand that inherits from the given +base+ command
|
14
|
+
# and stores the class in the +Help+ constant of +base+. When called,
|
15
|
+
# the command displays a help screen including information for all
|
16
|
+
# commands and then exits.
|
17
|
+
#
|
18
|
+
# The last argument can be a configuration hash, which accepts the
|
19
|
+
# following options:
|
20
|
+
#
|
21
|
+
# [:options] If +true+, will add a help option to the +base+
|
22
|
+
# command.
|
23
|
+
# [:switches] The switches used when creating the help option.
|
24
|
+
# [:exit] If +true+, +exit+ will be called when the command is
|
25
|
+
# done.
|
26
|
+
# [:include_root] Includes the root command when displaying a command's
|
27
|
+
# usage.
|
28
|
+
def create(*args)
|
29
|
+
opts, base = args.extract_ribbon!, args.shift
|
30
|
+
add_options_to! base, opts if opts.options? true
|
31
|
+
base.const_set(:Help, Class.new(base)).tap do |help_command|
|
32
|
+
help_command.when_called do |options, args|
|
33
|
+
# TODO: implement a way to specify a command to the help option
|
34
|
+
# and command.
|
35
|
+
# display_for options.command || args.pop
|
36
|
+
display_for base.root, opts
|
37
|
+
exit if opts.exit? true
|
38
|
+
end
|
41
39
|
end
|
42
40
|
end
|
43
|
-
end
|
44
41
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
42
|
+
# Displays a very simple help screen for the given command and all its
|
43
|
+
# subcommands.
|
44
|
+
#
|
45
|
+
# The last argument can be a configuration hash, which accepts the
|
46
|
+
# following options:
|
47
|
+
#
|
48
|
+
# [:include_root] Includes the root command when displaying a command's
|
49
|
+
# usage.
|
50
|
+
def display_for(*args)
|
51
|
+
options, command = args.extract_ribbon!, args.shift
|
52
|
+
puts Template.for(command, options) if command.options.any?
|
53
|
+
command.subcommands.each { |subcommand| display_for(subcommand, options) }
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
# Adds a special help option to the given +command+.
|
59
|
+
#
|
60
|
+
# The last argument can be a configuration hash, which accepts the
|
61
|
+
# following options:
|
62
|
+
#
|
63
|
+
# [:switches] The switches used when creating the help option.
|
64
|
+
def add_options_to!(*args)
|
65
|
+
opts, command = args.extract_ribbon!, args.shift
|
66
|
+
switches = opts.switches? %w(-h --help)
|
67
|
+
description = opts.description? 'Show usage information and exit.'
|
68
|
+
command.option :acclaim_help, *switches, description
|
69
|
+
end
|
70
|
+
|
50
71
|
end
|
51
72
|
|
52
73
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'erb'
|
2
|
+
require 'ribbon/core_ext/array'
|
2
3
|
|
3
4
|
module Acclaim
|
4
5
|
class Command
|
@@ -7,20 +8,38 @@ module Acclaim
|
|
7
8
|
# Manages help templates.
|
8
9
|
module Template
|
9
10
|
|
10
|
-
#
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
# The class methods.
|
12
|
+
class << self
|
13
|
+
|
14
|
+
# Returns the +template+ folder relative to this directory.
|
15
|
+
def folder
|
16
|
+
File.join File.dirname(__FILE__), 'template'
|
17
|
+
end
|
18
|
+
|
19
|
+
# Loads the contents of a template file from the template #folder.
|
20
|
+
def load(template_file)
|
21
|
+
File.read File.join(folder, template_file)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Creates a new ERB instance with the contents of +template+.
|
25
|
+
def create_from(template_file)
|
26
|
+
ERB.new load(template_file), nil, '%<>'
|
27
|
+
end
|
28
|
+
|
29
|
+
# Computes the result of the template +file+ using the +command+'s
|
30
|
+
# binding.
|
31
|
+
def for(*args)
|
32
|
+
template_options, command = args.extract_ribbon!, args.shift
|
33
|
+
template = create_from template_options.file?('command.erb')
|
34
|
+
b = command.instance_eval { binding }
|
35
|
+
# Since blocks are closures, the binding has access to the
|
36
|
+
# template_options ribbon:
|
37
|
+
#
|
38
|
+
# p b.eval 'template_options'
|
39
|
+
# => {}
|
40
|
+
template.result b
|
41
|
+
end
|
17
42
|
|
18
|
-
# Computes the result of the template +file+ using the +command+'s
|
19
|
-
# binding.
|
20
|
-
def self.for(command, file = 'command.erb')
|
21
|
-
template = self.load file
|
22
|
-
b = command.instance_eval { binding }
|
23
|
-
template.result b
|
24
43
|
end
|
25
44
|
|
26
45
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
<% unless root? or options.empty? %>
|
2
|
-
Command '<%=
|
2
|
+
Command '<%= full_line include_root: template_options.include_root? %>':
|
3
3
|
<% end %>
|
4
4
|
|
5
5
|
<% options.each do |option| %>
|
6
|
-
<%= option.names.join ', ' %>
|
6
|
+
<%= option.names.join ', ' %>
|
7
|
+
<%= option.description %>
|
7
8
|
<% end %>
|
8
9
|
|
@@ -1,43 +1,53 @@
|
|
1
|
+
require 'ribbon/core_ext/array'
|
2
|
+
|
1
3
|
module Acclaim
|
2
4
|
class Command
|
3
5
|
|
4
6
|
# Module which adds version query support to a command.
|
5
7
|
module Version
|
6
8
|
|
7
|
-
#
|
8
|
-
|
9
|
-
# The last argument is an option +Hash+, which accepts the following
|
10
|
-
# options:
|
11
|
-
#
|
12
|
-
# [:switches] The switches used when creating the version option.
|
13
|
-
def self.add_options_to!(command, opts = {})
|
14
|
-
switches = opts.fetch :switches, %w(-v --version)
|
15
|
-
description = opts.fetch :description, 'Show version and exit.'
|
16
|
-
command.option :acclaim_version, *switches, description
|
17
|
-
end
|
9
|
+
# The class methods.
|
10
|
+
class << self
|
18
11
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
12
|
+
# Creates a <tt>version</tt> subcommand that inherits from the given
|
13
|
+
# +base+ command and stores the class in the +Version+ constant of
|
14
|
+
# +base+. When called, the command displays the +version_string+ of the
|
15
|
+
# program and then exits.
|
16
|
+
#
|
17
|
+
# The last argument can be a configuration hash, which accepts the
|
18
|
+
# following options:
|
19
|
+
#
|
20
|
+
# [:options] If +true+, will add a version option to the +base+
|
21
|
+
# command.
|
22
|
+
# [:switches] The switches used when creating the version option.
|
23
|
+
# [:exit] If +true+, +exit+ will be called when the command is
|
24
|
+
# done.
|
25
|
+
def create(*args)
|
26
|
+
opts, base, version_string = args.extract_ribbon!, args.shift, args.shift
|
27
|
+
add_options_to! base, opts if opts.options? true
|
28
|
+
base.const_set(:Version, Class.new(base)).tap do |version_command|
|
29
|
+
version_command.when_called do |options, args|
|
30
|
+
puts version_string
|
31
|
+
exit if opts.exit? true
|
32
|
+
end
|
39
33
|
end
|
40
34
|
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# Adds a special version option to the given +command+.
|
39
|
+
#
|
40
|
+
# The last argument can be a configuration hash, which accepts the
|
41
|
+
# following options:
|
42
|
+
#
|
43
|
+
# [:switches] The switches used when creating the version option.
|
44
|
+
def add_options_to!(*args)
|
45
|
+
opts, command = args.extract_ribbon!, args.shift
|
46
|
+
switches = opts.switches? %w(-v --version)
|
47
|
+
description = opts.description? 'Show version and exit.'
|
48
|
+
command.option :acclaim_version, *switches, description
|
49
|
+
end
|
50
|
+
|
41
51
|
end
|
42
52
|
|
43
53
|
end
|
@@ -61,13 +61,13 @@ module Acclaim
|
|
61
61
|
# args = %w(-F log.txt --verbose arg1 arg2)
|
62
62
|
# options = []
|
63
63
|
# options << Option.new(:file, '-F', arity: [1,0], required: true)
|
64
|
-
# options << Option.new(:verbose
|
64
|
+
# options << Option.new(:verbose)
|
65
65
|
#
|
66
66
|
# Option::Parser.new(args, options).parse!
|
67
|
-
#
|
67
|
+
# => {file: "log.txt", verbose: true}
|
68
68
|
#
|
69
69
|
# args
|
70
|
-
#
|
70
|
+
# => ["arg1", "arg2"]
|
71
71
|
def parse!
|
72
72
|
preprocess_argv!
|
73
73
|
parse_values!
|
@@ -88,8 +88,8 @@ module Acclaim
|
|
88
88
|
def split_multiple_short_options!
|
89
89
|
argv.find_all { |arg| arg =~ MULTIPLE_SHORT_SWITCHES }.each do |multiples|
|
90
90
|
multiples_index = argv.index multiples
|
91
|
-
argv.
|
92
|
-
switches = multiples.sub
|
91
|
+
argv.delete_at multiples_index
|
92
|
+
switches = multiples.sub(/^-/, '').split(//).each { |letter| letter.prepend '-' }
|
93
93
|
argv.insert multiples_index, *switches
|
94
94
|
end
|
95
95
|
end
|
@@ -103,7 +103,7 @@ module Acclaim
|
|
103
103
|
def normalize_parameters!
|
104
104
|
argv.find_all { |arg| arg =~ SWITCH_PARAM_EQUALS }.each do |switch|
|
105
105
|
switch_index = argv.index switch
|
106
|
-
argv.
|
106
|
+
argv.delete_at switch_index
|
107
107
|
switch, params = switch.split /\=/
|
108
108
|
params = (params or '').split /,/
|
109
109
|
argv.insert switch_index, *[ switch, *params ]
|
@@ -113,24 +113,24 @@ module Acclaim
|
|
113
113
|
# Parses the options and their arguments, associating that information
|
114
114
|
# with a Ribbon instance.
|
115
115
|
def parse_values!
|
116
|
-
|
116
|
+
values = Ribbon.wrap
|
117
117
|
options.each do |option|
|
118
118
|
key = option.key
|
119
|
-
|
119
|
+
values[key] = option.default unless values.has_key? key
|
120
120
|
switches = argv.find_all { |switch| option =~ switch }
|
121
121
|
Error.raise_missing_required option if option.required? and switches.empty?
|
122
122
|
Error.raise_multiple option if option.on_multiple == :raise and switches.count > 1
|
123
123
|
switches.each do |switch|
|
124
124
|
if option.flag?
|
125
|
-
found_boolean option, ribbon
|
125
|
+
found_boolean option, values.ribbon
|
126
126
|
argv.delete_at argv.index(switch)
|
127
127
|
else
|
128
128
|
params = extract_parameters_of! option, switch
|
129
|
-
found_params_for option, params, ribbon
|
129
|
+
found_params_for option, params, values.ribbon
|
130
130
|
end
|
131
131
|
end
|
132
132
|
end
|
133
|
-
ribbon
|
133
|
+
values.ribbon
|
134
134
|
end
|
135
135
|
|
136
136
|
# Finds the +switch+ in #argv and scans the next +option.arity.total+
|
@@ -179,10 +179,10 @@ module Acclaim
|
|
179
179
|
params = option.convert_parameters *params
|
180
180
|
if handler = option.handler then handler.call ribbon, params
|
181
181
|
else
|
182
|
-
key = option.key
|
182
|
+
key = option.key
|
183
183
|
value = option.arity.total == 1 ? params.first : params
|
184
184
|
value = [*ribbon[key], *value] if option.on_multiple == :append
|
185
|
-
ribbon[
|
185
|
+
ribbon[key] = value unless params.empty?
|
186
186
|
end
|
187
187
|
end
|
188
188
|
|
@@ -191,7 +191,7 @@ module Acclaim
|
|
191
191
|
# be set to <tt>true</tt>.
|
192
192
|
def found_boolean(option, ribbon = Ribbon.new)
|
193
193
|
if handler = option.handler then handler.call ribbon
|
194
|
-
else ribbon[option.key
|
194
|
+
else ribbon[option.key] = true end
|
195
195
|
end
|
196
196
|
|
197
197
|
end
|
@@ -12,19 +12,19 @@ module Acclaim
|
|
12
12
|
# <tt>'-mult'</tt> should match MULTIPLE_SHORT_SWITCHES, and will be
|
13
13
|
# split into <tt>%w(-m -u -l -t)</tt>, which in turn should match this
|
14
14
|
# regular expression.
|
15
|
-
SHORT_SWITCH = /\A
|
15
|
+
SHORT_SWITCH = /\A-[a-zA-Z_]\Z/.freeze
|
16
16
|
|
17
17
|
# Regular expression for a long option switch.
|
18
18
|
#
|
19
19
|
# Examples: <tt>--long; --no-feature; --with_underscore;
|
20
20
|
# --_private-option; --1-1</tt>
|
21
|
-
LONG_SWITCH = /\A
|
21
|
+
LONG_SWITCH = /\A--\w+(-\w+)*\Z/.freeze
|
22
22
|
|
23
23
|
# Regular expression for multiple short options in a single "short"
|
24
24
|
# switch.
|
25
25
|
#
|
26
26
|
# Examples: <tt>-xvf; -abc; -de_f</tt>
|
27
|
-
MULTIPLE_SHORT_SWITCHES = /\A
|
27
|
+
MULTIPLE_SHORT_SWITCHES = /\A-[a-zA-Z_]{2,}\Z/.freeze
|
28
28
|
|
29
29
|
# Regular expression for a long switch connected to its parameters with
|
30
30
|
# an equal sign. Multiple parameters are be separated by commas.
|
@@ -40,16 +40,17 @@ module Acclaim
|
|
40
40
|
# <tt>'--weird=,PARAM2'</tt> will become
|
41
41
|
# <tt>['--weird', '', 'PARAM2']</tt> when it is split up. What to make
|
42
42
|
# of those isn't a decision for a preprocessor.
|
43
|
-
SWITCH_PARAM_EQUALS = /\A
|
43
|
+
SWITCH_PARAM_EQUALS = /\A--\w+(-\w+)*=(,*\w*)*\Z/.freeze
|
44
44
|
|
45
45
|
# Regular expression for any kind of option switch.
|
46
|
-
SWITCH =
|
46
|
+
SWITCH = ::Regexp.union(SHORT_SWITCH, LONG_SWITCH,
|
47
|
+
MULTIPLE_SHORT_SWITCHES, SWITCH_PARAM_EQUALS).freeze
|
47
48
|
|
48
49
|
# Regular expression for the string that separates options and their
|
49
50
|
# parameters from arguments like filenames.
|
50
51
|
#
|
51
52
|
# Examples: <tt>--; ---</tt>
|
52
|
-
ARGUMENT_SEPARATOR = /\A-{2,}\Z
|
53
|
+
ARGUMENT_SEPARATOR = /\A-{2,}\Z/.freeze
|
53
54
|
|
54
55
|
end
|
55
56
|
|
data/lib/acclaim/version.rb
CHANGED
@@ -0,0 +1,238 @@
|
|
1
|
+
require 'acclaim/option/parser/regexp'
|
2
|
+
|
3
|
+
describe Acclaim::Option::Parser::Regexp do
|
4
|
+
|
5
|
+
# Generate one helper for each constant in the described module.
|
6
|
+
described_class.constants.each do |constant|
|
7
|
+
let(constant.to_s.downcase.to_sym) { described_class.const_get constant }
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:short_option) { '-o' }
|
11
|
+
let(:long_option) { '--option' }
|
12
|
+
let(:multiple_short_options) { '-option' }
|
13
|
+
let(:long_option_equals_sign) { '--option=' }
|
14
|
+
let(:long_option_equals_sign_value) { '--option=VALUE' }
|
15
|
+
let(:long_option_equals_sign_values) { '--option=VALUE1,VALUE2,VALUE3' }
|
16
|
+
let(:long_option_equals_sign_comma_values) { '--option=,VALUE2,VALUE3' }
|
17
|
+
let(:long_option_equals_sign_empty_commas) { '--option=,,' }
|
18
|
+
let(:double_argument_separator) { '--' }
|
19
|
+
let(:triple_argument_separator) { '---' }
|
20
|
+
let(:long_option_with_separators) { '--my-option' }
|
21
|
+
let(:short_option_underscore) { '-_' }
|
22
|
+
let(:long_option_underscore) { '--_' }
|
23
|
+
let(:multiple_short_options_underscore) { '-many_options' }
|
24
|
+
let(:long_option_equals_sign_underscore) { '--my_option=' }
|
25
|
+
let(:short_option_with_numbers) { '-5' }
|
26
|
+
let(:multiple_short_options_with_numbers) { '-1234567890' }
|
27
|
+
let(:long_option_equals_sign_and_numbers) { '--1234567890=' }
|
28
|
+
let(:long_option_with_numbers) { '--1234567890' }
|
29
|
+
|
30
|
+
describe 'SHORT_SWITCH' do
|
31
|
+
it 'should match short options' do
|
32
|
+
short_option.should match(short_switch)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should not match long options' do
|
36
|
+
long_option.should_not match(short_switch)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should not match multiple short options' do
|
40
|
+
multiple_short_options.should_not match(short_switch)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should not match long options with an equals sign' do
|
44
|
+
long_option_equals_sign.should_not match(short_switch)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should not match a two-dash argument separator' do
|
48
|
+
double_argument_separator.should_not match(short_switch)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should not match a three-dash argument separator' do
|
52
|
+
triple_argument_separator.should_not match(short_switch)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should consider underscores as valid characters' do
|
56
|
+
short_option_underscore.should match(short_switch)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should not consider digits as valid characters' do
|
60
|
+
short_option_with_numbers.should_not match(short_switch)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'LONG_SWITCH' do
|
65
|
+
it 'should not match short options' do
|
66
|
+
short_option.should_not match(long_switch)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should match long options' do
|
70
|
+
long_option.should match(long_switch)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should not match multiple short options' do
|
74
|
+
multiple_short_options.should_not match(long_switch)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should not match long options with an equals sign' do
|
78
|
+
long_option_equals_sign.should_not match(long_switch)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should not match a two-dash argument separator' do
|
82
|
+
double_argument_separator.should_not match(long_switch)
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should not match a three-dash argument separator' do
|
86
|
+
triple_argument_separator.should_not match(long_switch)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should consider underscores as valid characters' do
|
90
|
+
long_option_underscore.should match(long_switch)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should consider digits as valid characters' do
|
94
|
+
long_option_with_numbers.should match(long_switch)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should allow dashes as word separators' do
|
98
|
+
long_option_with_separators.should match(long_switch)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe 'MULTIPLE_SHORT_SWITCHES' do
|
103
|
+
it 'should not match short options' do
|
104
|
+
short_option.should_not match(multiple_short_switches)
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'should not match long options' do
|
108
|
+
long_option.should_not match(multiple_short_switches)
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should match multiple short options' do
|
112
|
+
multiple_short_options.should match(multiple_short_switches)
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should not match long options with an equals sign' do
|
116
|
+
long_option_equals_sign.should_not match(multiple_short_switches)
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should not match a two-dash argument separator' do
|
120
|
+
double_argument_separator.should_not match(multiple_short_switches)
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'should not match a three-dash argument separator' do
|
124
|
+
triple_argument_separator.should_not match(multiple_short_switches)
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should consider underscores as valid characters' do
|
128
|
+
multiple_short_options_underscore.should match(multiple_short_switches)
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should not consider digits as valid characters' do
|
132
|
+
multiple_short_options_with_numbers.should_not match(multiple_short_switches)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe 'SWITCH_PARAM_EQUALS' do
|
137
|
+
it 'should not match short options' do
|
138
|
+
short_option.should_not match(switch_param_equals)
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should not match long options' do
|
142
|
+
long_option.should_not match(switch_param_equals)
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'should not match multiple short options' do
|
146
|
+
multiple_short_options.should_not match(switch_param_equals)
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should match long options with an equals sign' do
|
150
|
+
long_option_equals_sign.should match(switch_param_equals)
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should not match a two-dash argument separator' do
|
154
|
+
double_argument_separator.should_not match(switch_param_equals)
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'should not match a three-dash argument separator' do
|
158
|
+
triple_argument_separator.should_not match(switch_param_equals)
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'should consider underscores as valid characters' do
|
162
|
+
long_option_equals_sign_underscore.should match(switch_param_equals)
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'should consider digits as valid characters' do
|
166
|
+
long_option_equals_sign_and_numbers.should match(switch_param_equals)
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'should match a long option with an equals sign followed by a value' do
|
170
|
+
long_option_equals_sign_value.should match(switch_param_equals)
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'should match a long option with an equals sign followed by comma-separated values' do
|
174
|
+
long_option_equals_sign_values.should match(switch_param_equals)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'should match a long option with an equals sign with a comma before the values' do
|
178
|
+
long_option_equals_sign_comma_values.should match(switch_param_equals)
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'should match a long option with an equals sign followed by commas' do
|
182
|
+
long_option_equals_sign_empty_commas.should match(switch_param_equals)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe 'SWITCH' do
|
187
|
+
it 'should match short options' do
|
188
|
+
short_option.should match(switch)
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'should match long options' do
|
192
|
+
long_option.should match(switch)
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'should match multiple short options' do
|
196
|
+
multiple_short_options.should match(switch)
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'should match long options with an equals sign' do
|
200
|
+
long_option_equals_sign.should match(switch)
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'should not match a two-dash argument separator' do
|
204
|
+
double_argument_separator.should_not match(switch)
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'should not match a three-dash argument separator' do
|
208
|
+
triple_argument_separator.should_not match(switch)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
describe 'ARGUMENT_SEPARATOR' do
|
213
|
+
it 'should not match short options' do
|
214
|
+
short_option.should_not match(argument_separator)
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'should not match long options' do
|
218
|
+
long_option.should_not match(argument_separator)
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'should not match multiple short options' do
|
222
|
+
multiple_short_options.should_not match(argument_separator)
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'should not match long options with an equals sign' do
|
226
|
+
long_option_equals_sign.should_not match(argument_separator)
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'should match a two-dash argument separator' do
|
230
|
+
double_argument_separator.should match(argument_separator)
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'should match a three-dash argument separator' do
|
234
|
+
triple_argument_separator.should match(argument_separator)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
end
|
@@ -18,14 +18,14 @@ describe Acclaim::Option::Parser do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
context 'when given a long switch with multiple parameters separated by an equals sign' do
|
21
|
-
let!(:args) { %w(--files
|
21
|
+
let!(:args) { %w(--files=FILE1,FILE2,FILE3) }
|
22
22
|
|
23
23
|
it 'should separate the switch and the parameters' do
|
24
24
|
subject.parse!
|
25
25
|
args.should == %w(--files FILE1 FILE2 FILE3)
|
26
26
|
end
|
27
27
|
|
28
|
-
context 'but
|
28
|
+
context 'but without a first parameter' do
|
29
29
|
let!(:args) { %w(--files=,FILE2,FILE3) }
|
30
30
|
|
31
31
|
it 'should treat the first parameter as if it was an empty string' do
|
@@ -35,7 +35,7 @@ describe Acclaim::Option::Parser do
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
context 'when given a long
|
38
|
+
context 'when given a long switch with an equals sign' do
|
39
39
|
context 'but no parameters' do
|
40
40
|
let!(:args) { %w(--none=) }
|
41
41
|
|
data/spec/acclaim/option_spec.rb
CHANGED
@@ -164,7 +164,7 @@ describe Acclaim::Option do
|
|
164
164
|
|
165
165
|
context 'when the option was initialized with Date as its type' do
|
166
166
|
let(:type) { Date }
|
167
|
-
let(:date) {
|
167
|
+
let(:date) { type.today }
|
168
168
|
let(:params) { [date.to_s] }
|
169
169
|
|
170
170
|
it 'should convert the parameters to dates' do
|
@@ -174,7 +174,7 @@ describe Acclaim::Option do
|
|
174
174
|
|
175
175
|
context 'when the option was initialized with DateTime as its type' do
|
176
176
|
let(:type) { DateTime }
|
177
|
-
let(:date_time) {
|
177
|
+
let(:date_time) { type.parse type.now.to_s }
|
178
178
|
let(:params) { [date_time.to_s] }
|
179
179
|
|
180
180
|
it 'should convert the parameters to dates/times' do
|
@@ -184,7 +184,7 @@ describe Acclaim::Option do
|
|
184
184
|
|
185
185
|
context 'when the option was initialized with Time as its type' do
|
186
186
|
let(:type) { Time }
|
187
|
-
let(:time) {
|
187
|
+
let(:time) { type.parse type.now.to_s }
|
188
188
|
let(:params) { [time.to_s] }
|
189
189
|
|
190
190
|
it 'should convert the parameters to times' do
|
@@ -194,7 +194,7 @@ describe Acclaim::Option do
|
|
194
194
|
|
195
195
|
context 'when the option was initialized with URI as its type' do
|
196
196
|
let(:type) { URI }
|
197
|
-
let(:uri) {
|
197
|
+
let(:uri) { type.parse 'https://github.com/matheusmoreira/acclaim' }
|
198
198
|
let(:params) { [uri.to_s] }
|
199
199
|
|
200
200
|
it 'should convert the parameters to URIs' do
|
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.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-01-
|
12
|
+
date: 2012-01-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ribbon
|
16
|
-
requirement: &
|
16
|
+
requirement: &20746840 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *20746840
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &20745700 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *20745700
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rookie
|
38
|
-
requirement: &
|
38
|
+
requirement: &20744980 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *20744980
|
47
47
|
description: Command-line option parser and command interface.
|
48
48
|
email: matheus.a.m.moreira@gmail.com
|
49
49
|
executables: []
|
@@ -78,6 +78,7 @@ files:
|
|
78
78
|
- lib/acclaim/version.rb
|
79
79
|
- spec/acclaim/command_spec.rb
|
80
80
|
- spec/acclaim/option/arity_spec.rb
|
81
|
+
- spec/acclaim/option/parser/regexp_spec.rb
|
81
82
|
- spec/acclaim/option/parser_spec.rb
|
82
83
|
- spec/acclaim/option_spec.rb
|
83
84
|
homepage: https://github.com/matheusmoreira/acclaim
|
@@ -94,7 +95,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
95
|
version: '0'
|
95
96
|
segments:
|
96
97
|
- 0
|
97
|
-
hash: -
|
98
|
+
hash: -1211294602011748853
|
98
99
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
100
|
none: false
|
100
101
|
requirements:
|
@@ -103,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
104
|
version: '0'
|
104
105
|
segments:
|
105
106
|
- 0
|
106
|
-
hash: -
|
107
|
+
hash: -1211294602011748853
|
107
108
|
requirements: []
|
108
109
|
rubyforge_project:
|
109
110
|
rubygems_version: 1.8.10
|