argser 1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,186 @@
1
+ # INTRODUCTION
2
+
3
+ Argser (from "ARGuments parSER") is a library that aims to simplify the process of parsing arguments in command line scripts written in Ruby. It provides an easy way to specify which parameters are valid, their type or format, error conditions, description, etc. In that way, it reduces the need to write code specificaly to parse and validate such arguments.
4
+
5
+ The idea is pretty simple. To be able to use the arguments passed when the script was executed in a easy and consistent way, you only need to specify some general options for the application, a list of parameters and some properties that must hold for both, parameters and what is called the 'remaining array' (an array with strings that don't belong to any parameter).
6
+
7
+ # INSTALLATION
8
+
9
+ ```
10
+ gem install argser
11
+ ```
12
+
13
+ # USAGE
14
+
15
+ ```ruby
16
+ require 'argser'
17
+
18
+ Argser::Parser.new({
19
+ options: {...general options...},
20
+ params: {...parameters options...},
21
+ remaining: {...remaining array options...}
22
+ })
23
+ ```
24
+
25
+ ## GENERAL OPTIONS
26
+
27
+ - <code>:description</code>, a string containing the description of the application (default: "")
28
+ - <code>:usage</code>, a string describing how to use the application (default: "")
29
+ - <code>:details</code>, a string containing details about the application (default: "")
30
+ - <code>:info</code>, a string printer bellow errors indicating how to find more information about them (default: "For more information try '--help'")
31
+ - <code>:unknown</code>, a string with the message to show when a parameter is not known (default: "Unknown parameter '$p'")
32
+ - <code>:fatal</code>, a string with the message to show when an internal error is found while parsing parameters (default: "An internal error was found")
33
+ - <code>:help</code>, a boolean value indicating if the parser should automatically display the help if parameter :help is given (default: true)
34
+
35
+ ## PARAMETERS OPTIONS
36
+
37
+ - <code>:shortcut</code>, a symbol used as a shortcut for this parameter (default: nil)
38
+ - <code>:type</code>, symbol indicating the type of this parameter (default: :string)
39
+ - <code>:default</code>, the default value if not other value is provided (default: '')
40
+ - <code>:required</code>, a boolean value indicating if this parameter is required or not
41
+ - <code>:sanitize</code>, a function to sanitize the value given (return the identifier of a message to show it or the sanitized value the parser should save)
42
+ - <code>:callback</code>, a function to call to do something with the parameter
43
+ - <code>:messages</code> A hash with all available messages to show where the key is used as an identifier (:help, :type and :required are created by default)
44
+
45
+ ## REMAINING ARRAY OPTIONS
46
+
47
+ - <code>:type</code>, a symbol indicating the type of this parameter (default: :string)
48
+ - <code>:default</code>, the default value if not other value is provided (default: '')
49
+ - <code>:minimum</code>, minimum number of strings allowed
50
+ - <code>:maximum</code>, maximum number of strings allowed
51
+ - <code>:sanitize</code>, a function to sanitize the value given (return the identifier of a message to show it or the sanitized value the parser should save)
52
+ - <code>:callback</code>, a function to call to do something with the parameter
53
+ - <code>:messages</code>, hash with all available messages to show where the key is used as an identifier (:help, :type and :required are created by default)
54
+
55
+ ## AVAILABLE TYPES
56
+
57
+ Here is the list of types:
58
+
59
+ - <code>:integer</code>, integer value (default: 0)
60
+ - <code>:float</code>, float value (default: 0.0)
61
+ - <code>:boolean</code>, boolean value (default: false)
62
+ - <code>:alpanumeric</code>, letters and numbers (default: '')
63
+ - <code>:letters</code>, letters (default: '')
64
+ - <code>:words</code>, words (default: '')
65
+ - <code>:range</code>, integer range (default: [0, 0])
66
+ - <code>:interval</code>, float range (default: [0.0, 0.0])
67
+ - <code>:string</code>, string (default: '')
68
+
69
+ The default type is <code>:string</code>
70
+
71
+ # EXAMPLE
72
+
73
+ ```ruby
74
+ require '../lib/argser/parser.rb'
75
+
76
+ parser = Argser::Parser.new({
77
+ options: {
78
+ description: "This is a greeting application",
79
+ usage: "greeting [OPTIONS] NAME",
80
+ details: "Provided your age and your name, this application will greet you in a unique way.",
81
+ info: "For more information contact me at foo@/dev/null.com or try '--help'",
82
+ unknown: "What's '$p'?",
83
+ fatal: "There has been a weird error!!",
84
+ help: true
85
+ },
86
+ params: {
87
+ age: {
88
+ shortcut: :a,
89
+ default: 18,
90
+ type: :integer,
91
+ sanitize: lambda {|value, default| (value >= 18) ? value : :young},
92
+ messages: {
93
+ help: "Specify your age",
94
+ type: "I can't believe you're '$v' years old",
95
+ young: "You can't use this application unless you're older than 18!"
96
+ }
97
+ }
98
+ },
99
+ remaining: {
100
+ type: /[A-Z][A-Za-z]+\s[A-Z][A-Za-z]+/,
101
+ minimum: 1,
102
+ maximum: 1,
103
+ callback: lambda {|values, default| puts "Alright, I got your name!"},
104
+ messages: {
105
+ help: "Specify your name and surname",
106
+ type: "What!? Your name is '$v'!?"
107
+ }
108
+ }
109
+ })
110
+
111
+ parser.parse(ARGV)
112
+
113
+ comment = ''
114
+ if (parser.param? :age)
115
+ comment = case parser.param(:age)
116
+ when 18..20 then "you're a teenager!"
117
+ when 21..30 then "you're a young man!"
118
+ when 30..99 then "you're a little adult!"
119
+ end
120
+ else
121
+ comment = 'how old are you?'
122
+ end
123
+
124
+ puts "What's up #{parser.remaining[0]}? #{comment}"
125
+ ```
126
+
127
+ ## TESTS
128
+
129
+ ```bash
130
+ $ ruby greetings.rb --help
131
+ ```
132
+ ```
133
+ This is a greeting application
134
+
135
+ greeting [OPTIONS] NAME
136
+
137
+ -a --age Specify your age
138
+ -h --help Display this help and exit
139
+
140
+ Provided your age and your name, this application will greet you in a unique way.
141
+ ```
142
+
143
+ ```bash
144
+ $ ruby greetings.rb --age 20
145
+ ```
146
+ ```
147
+ Incorrect number of remaining arguments
148
+ For more information contact me at foo@/dev/null.com or try '--help'
149
+ ```
150
+
151
+ ```bash
152
+ $ ruby greetings.rb --age 10 "Dummy Name"
153
+ ```
154
+ ```
155
+ You can't use this application unless you're older than 18!
156
+ For more information contact me at foo@/dev/null.com or try '--help'
157
+ ```
158
+
159
+ ```bash
160
+ $ ruby greetings.rb --age 20 "Dummy Name" "Another Name"
161
+ ```
162
+ ```
163
+ Incorrect number of remaining arguments
164
+ For more information contact me at foo@/dev/null.com or try '--help'
165
+ ```
166
+
167
+ ```bash
168
+ $ ruby greetings.rb --age 20 "Dummy Name"
169
+ ```
170
+ ```
171
+ Alright, I got your name!
172
+ What's up Dummy Name? you're a teenager!
173
+ ```
174
+
175
+ ```bash
176
+ $ ruby greetings.rb "Dummy Name" --age 25
177
+ ```
178
+ ```
179
+ Alright, I got your name!
180
+ What's up Dummy Name? you're a young man!
181
+ ```
182
+
183
+ # AUTHOR
184
+
185
+ Matías Parodi © 2013
186
+ mparodilabs@gmail.com
@@ -0,0 +1,51 @@
1
+ require '../lib/argser/parser.rb'
2
+
3
+ parser = Argser::Parser.new({
4
+ options: {
5
+ description: "This is a greeting application",
6
+ usage: "greeting [OPTIONS] NAME",
7
+ details: "Provided your age and your name, this application will greet you in a unique way.",
8
+ info: "For more information contact me at foo@/dev/null.com or try '--help'",
9
+ unknown: "What's '$p'?",
10
+ fatal: "There has been a weird error!!",
11
+ help: true
12
+ },
13
+ params: {
14
+ age: {
15
+ shortcut: :a,
16
+ default: 18,
17
+ type: :integer,
18
+ sanitize: lambda {|value, default| (value >= 18) ? value : :young},
19
+ messages: {
20
+ help: "Specify your age",
21
+ type: "I can't believe you're '$v' years old",
22
+ young: "You can't use this application unless you're older than 18!"
23
+ }
24
+ }
25
+ },
26
+ remaining: {
27
+ type: /[A-Z][A-Za-z]+\s[A-Z][A-Za-z]+/,
28
+ minimum: 1,
29
+ maximum: 1,
30
+ callback: lambda {|values, default| puts "Alright, I got your name!"},
31
+ messages: {
32
+ help: "Specify your name and surname",
33
+ type: "What!? Your name is '$v'!?"
34
+ }
35
+ }
36
+ })
37
+
38
+ parser.parse(ARGV)
39
+
40
+ comment = ''
41
+ if (parser.param? :age)
42
+ comment = case parser.param(:age)
43
+ when 18..20 then "you're a teenager!"
44
+ when 21..30 then "you're a young man!"
45
+ when 30..99 then "you're a little adult!"
46
+ end
47
+ else
48
+ comment = 'how old are you?'
49
+ end
50
+
51
+ puts "What's up #{parser.remaining[0]}? #{comment}"
@@ -0,0 +1,300 @@
1
+ module Argser
2
+
3
+ class Parser
4
+
5
+ @tokens
6
+ @options
7
+ @params
8
+ @remaining
9
+
10
+ #Available types (:integer, :float, :boolean, :alpanumeric, :letters, :words, :range, :interval and :string)
11
+ TYPES = {
12
+ integer: [/^\s*\d+\s*$/, lambda {|value, match, default| value.to_i || 0}],
13
+ float: [/^\s*\d+\.\d+\s*$/, lambda {|value, match, default| value.to_f || 0.0}],
14
+ boolean: [/^\s*$/, lambda {|value, match, default| !default || false}],
15
+ letters: [/^\s*[A-Za-z]+\s*$/, lambda {|value, match, default| (!default) ? value.strip : (value || '').strip}],
16
+ alphanumeric: [/^\s*\w+\s*$/, lambda {|value, match, default| (!default) ? value.strip : (value || '').strip}],
17
+ words: [/^\s*[A-Za-z]+(?:\s+[A-Za-z]+)*\s*$/, lambda {|value, match, default| (!default) ? value.strip : (value || '').strip}],
18
+ range: [/^\s*(?:(\d+)\.\.(\d+)|(\d*)\.\.|\.\.(\d+))\s*$/, lambda {|value, match, default| (!default) ? [(match[0] || match[3]).to_i, (match[2] || match[4]).to_i] : [0,0]}],
19
+ interval: [/^\s*(?:(\d+(?:\.\d+)?)\.\.(\d+(?:\.\d+)?)|(\d*(?:\.\d+)?)\.\.|\.\.(\d+(?:\.\d+)?))\s*$/, lambda {|value, match, default| (!default) ? [(match[0] || match[3]).to_f, (match[2] || match[4]).to_f] : [0.0,0.0]}],
20
+ string: [/^.*$/, lambda {|value, match, default| value || ''}]
21
+ }
22
+
23
+ #Initialize the parser
24
+ def initialize(config)
25
+ @tokens, @options, @params, @remaining = {}, {}, {}, {}
26
+ init_options(config[:options] || {})
27
+ init_params(config[:params] || {})
28
+ init_remaining(config[:remaining] || {})
29
+ end
30
+
31
+ #Parse an array with arguments and associate each element to one of the parameters or to the remaining array
32
+ def parse(args)
33
+ begin
34
+ #Identify each element in the array of arguments
35
+ last_param = nil
36
+ args.each do |arg|
37
+ if (arg =~ /^--?\w+$/)
38
+ arg = arg.downcase
39
+
40
+ raise_message(@options[:unknown], arg) unless @tokens.has_key? arg
41
+ param = @params[@tokens[arg]]
42
+ param[:given] = arg
43
+ if (@params[@tokens[arg]][:type] != :boolean)
44
+ last_param = param
45
+ end
46
+
47
+ #If parameter :help was given and the parser is supposed to automatically display the help, do so
48
+ help if (param? :help) and (@options[:help])
49
+ else
50
+ if (last_param)
51
+ last_param[:value] = arg
52
+ last_param = nil
53
+ else
54
+ @remaining[:value] = [] if @remaining[:given] == 0
55
+ @remaining[:given] += 1
56
+ @remaining[:value].push arg
57
+ end
58
+ end
59
+ end
60
+
61
+ #Iterate over all parameters and process their values
62
+ @params.each do |token, param|
63
+ raise_message(param[:messages][:required], "--#{param[:token].to_s}") unless param?(token) or !param[:required]
64
+ validate_param(param)
65
+ sanitize(param)
66
+ end
67
+
68
+ #Process the value of the remaining array
69
+ raise_message(@remaining[:messages][:required]) unless (@remaining[:minimum] <= remaining?) and (remaining? <= @remaining[:maximum])
70
+ validate_remaining()
71
+ sanitize(@remaining)
72
+
73
+ #Invoke all callbacks
74
+ invoke_callbacks
75
+ rescue ParserError => error
76
+ #In case of error, print the reason and how to find more information
77
+ puts error.message
78
+ puts @options[:info] unless @options[:info].empty?
79
+ exit
80
+ end
81
+ end
82
+
83
+ #Check if a parameter was given
84
+ def param?(param)
85
+ (@tokens.has_key? param) ? !!@params[@tokens[param]][:given] : false
86
+ end
87
+
88
+ #Return the value of a parameter
89
+ def param(param)
90
+ (@tokens.has_key? param) ? @params[@tokens[param]][:value] : ''
91
+ end
92
+
93
+ #Returns the number of remaining strings that were found
94
+ def remaining?()
95
+ @remaining[:given]
96
+ end
97
+
98
+ #Return the remaining values
99
+ def remaining()
100
+ @remaining[:value]
101
+ end
102
+
103
+ #Return both parameters and remaining values in a hash
104
+ def dump
105
+ values = {}
106
+ @params.each do |token, param|
107
+ values[token] = param[:value]
108
+ end
109
+ {params: values, remaining: @remaining[:value]}
110
+ end
111
+
112
+ #Display the help and exit
113
+ def help
114
+ puts "#{@options[:description]}\n\n" unless @options[:description].empty?
115
+ puts "#{@options[:usage]}\n\n" unless @options[:usage].empty?
116
+ @params.each do |token, param|
117
+ token = "--#{token.to_s}"
118
+ shortcut = (param[:shortcut].is_a? Symbol) ? "-#{param[:shortcut]}" : ''
119
+ help = param[:messages][:help]
120
+ puts " #{shortcut.ljust(5, ' ')}#{token.ljust(20, ' ')}#{help}"
121
+ end
122
+ puts "\n"
123
+ puts "#{@options[:details]}" unless @options[:details].empty?
124
+ exit
125
+ end
126
+
127
+ private
128
+
129
+ #Available general options:
130
+ # :description A string containing the description of the application (default: "")
131
+ # :usage A string describing how to use the application (default: "")
132
+ # :details A string containing details about the application (default: "")
133
+ # :info A string printer bellow errors indicating how to find more information about them (default: "For more information try '--help'")
134
+ # :unknown A string with the message to show when a parameter is not known (default: "Unknown parameter '$p'")
135
+ # :fatal A string with the message to show when an internal error is found while parsing parameters (default: "An internal error was found")
136
+ # :help A boolean value indicating if the parser should automatically display the help if parameter :help is given (default: true)
137
+
138
+ #Save all options for the parser
139
+ def init_options(options={})
140
+ @options = {
141
+ description: "",
142
+ usage: "",
143
+ details: "",
144
+ info: "For more information try '--help'",
145
+ unknown: "Unknown parameter '$p'",
146
+ fatal: "An internal error was found",
147
+ help: true
148
+ }.merge options
149
+ end
150
+
151
+ #Available parameter options:
152
+ # :shortcut A symbol used as a shortcut for this parameter (default: nil)
153
+ # :type A symbol indicating the type of this parameter (default: :string)
154
+ # :default The default value if not other value is provided (default: '')
155
+ # :required A boolean value indicating if this parameter is required or not
156
+ # :sanitize A function to sanitize the value given (return the identifier of a message to show it or the sanitized value the parser should save)
157
+ # :callback A function to call to do something with the parameter
158
+ # :messages A hash with all available messages to show where the key is used as an identifier (:help, :type and :required are created by default)
159
+
160
+ #Save all parameters the parser should recognize
161
+ def init_params(params={})
162
+ #If the parser should recognize :help, add it
163
+ if (!params.has_key? :help) and (@options[:help])
164
+ params[:help] = {
165
+ shortcut: :h,
166
+ type: :boolean,
167
+ default: false,
168
+ messages: {
169
+ help: 'Display this help and exit'
170
+ }
171
+ }
172
+ end
173
+
174
+ #Save each param and overwrite default options
175
+ params.each do |token, param|
176
+ @params[token] = {
177
+ shortcut: nil,
178
+ type: :string,
179
+ default: '',
180
+ required: false,
181
+ sanitize: lambda {|value, default| value},
182
+ callback: lambda {|value, default|},
183
+ messages: {}
184
+ }.merge param
185
+
186
+ @params[token][:token] = token
187
+ @params[token][:value] = @params[token][:default]
188
+ @params[token][:given] = false
189
+
190
+ #Save messages, make sure :help, :type and :required is available
191
+ @params[token][:messages] = {
192
+ help: "",
193
+ type: "Invalid value '$v' for parameter '$p'",
194
+ required: "Parameter '$p' is required"
195
+ }.merge @params[token][:messages]
196
+
197
+ #Register all tokens for the parameter
198
+ @tokens[token] = token
199
+ @tokens["--#{token}"] = token
200
+ if (param[:shortcut].is_a? Symbol)
201
+ @tokens[param[:shortcut]] = token
202
+ @tokens["-#{param[:shortcut]}"] = token
203
+ end
204
+ end
205
+ end
206
+
207
+ #Available remaining array options:
208
+ # :type A symbol indicating the type of this parameter (default: :string)
209
+ # :default The default value if not other value is provided (default: '')
210
+ # :minimum Minimum number of strings allowed (default: 0)
211
+ # :maximum Maximum number of strings allowed (default: Infinity)
212
+ # :sanitize A function to sanitize the value given (return the identifier of a message to show it or the sanitized value the parser should save)
213
+ # :callback A function to call to do something with the parameter
214
+ # :messages A hash with all available messages to show where the key is used as an identifier (:help, :type and :required are created by default)
215
+
216
+ #Save options for remaining strings
217
+ def init_remaining(remaining={})
218
+ @remaining = {
219
+ type: :string,
220
+ default: [],
221
+ minimum: 0,
222
+ maximum: Float::INFINITY,
223
+ sanitize: lambda {|value, default| value},
224
+ callback: lambda {|value, default|},
225
+ messages: {}
226
+ }.merge remaining
227
+
228
+ @remaining[:value] = @remaining[:default]
229
+ @remaining[:given] = 0
230
+
231
+ #Save messages, make sure :help, :type and :required is available
232
+ @remaining[:messages] = {
233
+ help: "",
234
+ type: "Invalid value '$v'",
235
+ required: "Incorrect number of remaining arguments"
236
+ }.merge @remaining[:messages]
237
+ end
238
+
239
+ #Validate the value of a parameter based on its type
240
+ def validate_param(param)
241
+ #If the type is a symbol, it must be a valid type
242
+ if (param[:type].is_a? Symbol)
243
+ type = TYPES[param[:type]]
244
+ raise_message(param[:messages][:type], param[:token], param[:value]) if (param[:given]) and (param[:value].is_a? String) and !(match = type[0].match param[:value])
245
+ #Convert value to the correct type
246
+ param[:value] = type[1].call(param[:value], match, !param[:given])
247
+ else #Otherwise it must be a regexp and the value must match
248
+ raise_message(param[:messages][:type], param[:token], param[:value]) unless param[:value] =~ param[:type]
249
+ end
250
+ end
251
+
252
+ #Validate the value of the remaining array based on its type
253
+ def validate_remaining()
254
+ #If the type is a symbol, it must be a valid type
255
+ if (@remaining[:type].is_a? Symbol)
256
+ type = TYPES[@remaining[:type]]
257
+ @remaining[:value].each_with_index do |value, i|
258
+ raise_message(@remaining[:messages][:type], @remaining[:token], value) unless (@remaining[:given] == 0) or (match = type[0].match value)
259
+ #Convert value to the correct type
260
+ @remaining[:value][i] = type[1].call(value, match, @remaining[:given] == 0)
261
+ end
262
+ else #Otherwise it must be a regexp and the values must match
263
+ @remaining[:value].each do |value|
264
+ raise_message(@remaining[:messages][:type], @remaining[:token], value) unless value =~ @remaining[:type]
265
+ end
266
+ end
267
+ end
268
+
269
+ #Sanitize the value of the parameter, if a symbol is returned the associated message is shown
270
+ def sanitize(param)
271
+ value = param[:sanitize].call(param[:value], !param[:given])
272
+ raise_message(param[:messages][value], param[:token], param[:value]) if value.is_a? Symbol
273
+ #Update the value
274
+ param[:value] = value
275
+ end
276
+
277
+ #Invoke parameters and remaining array callbacks
278
+ def invoke_callbacks
279
+ @params.each do |token, param|
280
+ param[:callback].call(param[:value], !param[:given])
281
+ end
282
+ @remaining[:callback].call(@remaining[:value], !@remaining[:given])
283
+ end
284
+
285
+ #Raise an error message
286
+ def raise_message(message, token='', value='')
287
+ raise ParserError.new(message || @options[:fatal], token, value)
288
+ end
289
+
290
+ #Parser errors used to display messages ($p is replaced by the parameter used by the user, $v is replaced by the value given)
291
+ class ParserError < Exception
292
+ attr_reader :message
293
+ def initialize(message, token='', value='')
294
+ @message = message.gsub('$p', token.to_s).gsub('$v', value.to_s)
295
+ end
296
+ end
297
+
298
+ end
299
+
300
+ end
data/lib/argser.rb ADDED
@@ -0,0 +1,10 @@
1
+ #Argser is a library that aims to simplify the process of parsing arguments in command
2
+ #line scripts written in Ruby. It provides an easy way to specify which parameters are
3
+ #valid, their type or format, error conditions, description, etc. In that way, it
4
+ #reduces the need to write code specificaly to parse and validate such arguments.
5
+ #
6
+ #Author: Matías Parodi © 2013
7
+ #
8
+ module Argser
9
+ require 'argser/parser'
10
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: argser
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Matías Parodi
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-14 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Argser (from 'ARGuments parSER') is a library that aims to simplify the
15
+ process of parsing arguments in command line scripts written in Ruby. It provides
16
+ an easy way to specify which parameters are valid, their type or format, error conditions,
17
+ description, etc. In that way, it reduces the need to write code specificaly to
18
+ parse and validate such arguments. The idea is pretty simple. To be able to use
19
+ the arguments passed when the script was executed in a easy and consistent way,
20
+ you only need to specify some general options for the application, a list of parameters
21
+ and some properties that must hold for both, parameters and what is called the 'remaining
22
+ array' (an array with strings that don't belong to any parameter).
23
+ email:
24
+ - mparodilabs@gmail.com
25
+ executables: []
26
+ extensions: []
27
+ extra_rdoc_files: []
28
+ files:
29
+ - README.md
30
+ - lib/argser.rb
31
+ - lib/argser/parser.rb
32
+ - examples/greetings.rb
33
+ homepage: http://rubygems.org/gems/argser
34
+ licenses: []
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ requirements: []
52
+ rubyforge_project:
53
+ rubygems_version: 1.8.23
54
+ signing_key:
55
+ specification_version: 3
56
+ summary: Argser is a library that aims to simplify the process of parsing arguments
57
+ in command line scripts written in Ruby
58
+ test_files: []
59
+ has_rdoc: