acclaim 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|