hirobumi-argument_sensei 0.1.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.rdoc +57 -0
- data/Rakefile +40 -0
- data/lib/argument_sensei/commands.rb +259 -0
- data/lib/argument_sensei/version.rb +13 -0
- data/lib/argument_sensei.rb +7 -0
- data/test/test_helper.rb +9 -0
- data/test/unit/argument_sensei_test.rb +202 -0
- metadata +62 -0
data/README.rdoc
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
= ArgumentSensei
|
2
|
+
|
3
|
+
ArgumentSensei is yet another command-line argument parser with a minimal set of features.
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
sudo gem install hirobumi-argument_sensei -s http://gems.github.com --no-ri --no-rdoc
|
8
|
+
|
9
|
+
== Usage
|
10
|
+
|
11
|
+
require 'rubygems'
|
12
|
+
require 'argument_sensei'
|
13
|
+
|
14
|
+
commands = ArgumentSensei.define do
|
15
|
+
|
16
|
+
option 'help', :short => 'h' do
|
17
|
+
arguments 0
|
18
|
+
describe 'show this message'
|
19
|
+
action do
|
20
|
+
# commands to run when -h or --help is given.
|
21
|
+
end # action do
|
22
|
+
end # option 'help', :short => 'h' do
|
23
|
+
|
24
|
+
default 'help'
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
# ...
|
29
|
+
|
30
|
+
# in the place you want to run the codes...
|
31
|
+
commands.run!
|
32
|
+
|
33
|
+
|
34
|
+
== License
|
35
|
+
|
36
|
+
Copyright (c) 2009 Hirobumi Hama
|
37
|
+
|
38
|
+
Permission is hereby granted, free of charge, to any person
|
39
|
+
obtaining a copy of this software and associated documentation
|
40
|
+
files (the "Software"), to deal in the Software without
|
41
|
+
restriction, including without limitation the rights to use,
|
42
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
43
|
+
copies of the Software, and to permit persons to whom the
|
44
|
+
Software is furnished to do so, subject to the following
|
45
|
+
conditions:
|
46
|
+
|
47
|
+
The above copyright notice and this permission notice shall be
|
48
|
+
included in all copies or substantial portions of the Software.
|
49
|
+
|
50
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
51
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
52
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
53
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
54
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
55
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
56
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
57
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
require 'lib/argument_sensei/version'
|
6
|
+
|
7
|
+
task :default => :test
|
8
|
+
|
9
|
+
spec = Gem::Specification.new do |s|
|
10
|
+
s.name = 'argument_sensei'
|
11
|
+
s.version = ArgumentSensei::Version.to_s
|
12
|
+
s.has_rdoc = true
|
13
|
+
s.extra_rdoc_files = %w(README.rdoc)
|
14
|
+
s.rdoc_options = %w(--main README.rdoc)
|
15
|
+
s.summary = "ArgumentSensei is yet another command-line argument parser with a minimal set of features."
|
16
|
+
s.author = 'Hirobumi Hama'
|
17
|
+
s.email = 'hama@yoidore.org'
|
18
|
+
s.homepage = 'http://yoidore.org/argument_sensei'
|
19
|
+
s.files = %w(README.rdoc Rakefile) + Dir.glob("{lib,test}/**/*")
|
20
|
+
# s.executables = ['argument_sensei']
|
21
|
+
|
22
|
+
# s.add_dependency('gem_name', '~> 0.0.1')
|
23
|
+
end
|
24
|
+
|
25
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
26
|
+
pkg.gem_spec = spec
|
27
|
+
end
|
28
|
+
|
29
|
+
Rake::TestTask.new do |t|
|
30
|
+
t.libs << 'test'
|
31
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
32
|
+
t.verbose = true
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'Generate the gemspec to serve this Gem from Github'
|
36
|
+
task :github do
|
37
|
+
file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
|
38
|
+
File.open(file, 'w') {|f| f << spec.to_ruby }
|
39
|
+
puts "Created gemspec: #{file}"
|
40
|
+
end
|
@@ -0,0 +1,259 @@
|
|
1
|
+
module ArgumentSensei
|
2
|
+
|
3
|
+
class Commands
|
4
|
+
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
def initialize(opts = {})
|
8
|
+
@arguments = opts[:arguments] || ARGV || []
|
9
|
+
@options = opts[:options] || []
|
10
|
+
@queue = {}
|
11
|
+
@default = nil
|
12
|
+
end # def initialize(opts = {})
|
13
|
+
|
14
|
+
attr_reader :arguments, :options
|
15
|
+
|
16
|
+
def method_missing(method_name, *args, &block)
|
17
|
+
if @options.respond_to?(method_name)
|
18
|
+
@options.send(method_name, *args, &block)
|
19
|
+
else
|
20
|
+
raise(NameError.new("undefined local variable or method '#{method_name}' for both #{inspect} and its @options"))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# parses and runs actions if necessary, returns a hash of command-line options
|
25
|
+
def run!
|
26
|
+
count = 0
|
27
|
+
|
28
|
+
h = parse
|
29
|
+
keys = h.keys
|
30
|
+
|
31
|
+
opts = @options.select { |o| o[:priority] == :option && (keys.include?(o[:long]) || keys.include?(o[:short])) } || []
|
32
|
+
runs = @options.select { |o| o[:priority] == :runner && (keys.include?(o[:long]) || keys.include?(o[:short])) } || []
|
33
|
+
|
34
|
+
# TODO: Exception message can be more informative.
|
35
|
+
raise(RuntimeError.new(runs.map { |o| "--#{o[:long]}/-#{o[:short]}" }.join(' ') + ' cannot be ran at the same time')) if runs.length > 1
|
36
|
+
|
37
|
+
(opts + runs).each do |o|
|
38
|
+
next unless o[:action]
|
39
|
+
if h.keys.include?(o[:short]) || h.keys.include?(o[:long])
|
40
|
+
o[:action].call(h[o[:short] || o[:long]])
|
41
|
+
count += 1
|
42
|
+
end
|
43
|
+
end # @options.each do |o|
|
44
|
+
|
45
|
+
if count == 0 && !@default.nil? # runs default if given
|
46
|
+
definition(@default)[:action].call(nil)
|
47
|
+
end # if count == 0
|
48
|
+
|
49
|
+
end # def run!
|
50
|
+
|
51
|
+
# returns a hash of command-line options
|
52
|
+
def parse
|
53
|
+
arr = []
|
54
|
+
for_arguments = false
|
55
|
+
temp = []
|
56
|
+
|
57
|
+
# splits grouped booelean short options
|
58
|
+
@arguments.collect! do |x|
|
59
|
+
unless x =~ /^-\w{2,}/
|
60
|
+
x
|
61
|
+
else
|
62
|
+
x.gsub(/^-/, '').split(//).map do |y|
|
63
|
+
raise(ArgumentError.new("option #{y} (which takes #{definition(y)[:arguments]}) should not be combined (#{x})")) if definition(y) && definition(y)[:arguments] != 0
|
64
|
+
'-' + y
|
65
|
+
end # x.gsub(/^-/, '').split(//).map do |y|
|
66
|
+
end
|
67
|
+
end.flatten! # @arguments.collect! do |x|
|
68
|
+
|
69
|
+
@arguments.each do |x|
|
70
|
+
|
71
|
+
if for_arguments && ((argument_length(temp[0]) != :all && temp.length - 1 >= argument_length(temp[0])) || x =~ /^-+/)
|
72
|
+
arr << temp
|
73
|
+
for_arguments = false
|
74
|
+
temp = []
|
75
|
+
end # if for_arguments && temp.length - 1 >= argument_length(temp[0])
|
76
|
+
|
77
|
+
if x =~ /^-+/
|
78
|
+
unless option_defined?(x)
|
79
|
+
arr << x
|
80
|
+
else
|
81
|
+
for_arguments = true
|
82
|
+
temp << x
|
83
|
+
end
|
84
|
+
elsif for_arguments # if x =~ /^-+/
|
85
|
+
temp << x
|
86
|
+
else # elsif for_arguments if x =~ /^-+/
|
87
|
+
arr << x
|
88
|
+
end # end elsif for_arguments if x =~ /^-+/
|
89
|
+
|
90
|
+
end # each do |x|
|
91
|
+
|
92
|
+
arr << temp if temp.length > 0
|
93
|
+
|
94
|
+
hash = {}
|
95
|
+
hash[:orphans] = arr.select { |a| !a.is_a?(Array) }
|
96
|
+
(arr - hash[:orphans]).each do |a|
|
97
|
+
gsubbed = a[0].gsub(/^-+/, '')
|
98
|
+
if argument_length(gsubbed) == 0
|
99
|
+
hash[gsubbed] = true
|
100
|
+
else
|
101
|
+
hash[gsubbed] = a[1..-1]
|
102
|
+
end
|
103
|
+
end # (arr - hash[:orphans]).each do |a|
|
104
|
+
|
105
|
+
# make sure both :short and :long are filled if they are provided
|
106
|
+
each do |c|
|
107
|
+
short, long = [c[:short], c[:long]].map { |n| (n || '').gsub(/^-+/, '') }
|
108
|
+
next if short == '' || long == ''
|
109
|
+
|
110
|
+
if hash[short] || hash[long]
|
111
|
+
next if hash[short] == hash[long]
|
112
|
+
if hash[short].nil?
|
113
|
+
hash[short] = hash[long]
|
114
|
+
else
|
115
|
+
hash[long] = hash[short]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end # each do |c|
|
120
|
+
|
121
|
+
hash # returns
|
122
|
+
end # def parse
|
123
|
+
|
124
|
+
# finds a detailed option for given name
|
125
|
+
def definition(name)
|
126
|
+
n = name.gsub(/^-+/, '')
|
127
|
+
select { |h| h[:short] == n || h[:long] == n }[0] # can be nil
|
128
|
+
end
|
129
|
+
|
130
|
+
def option_defined?(name)
|
131
|
+
!!definition(name)
|
132
|
+
end # def defined?(name)
|
133
|
+
|
134
|
+
def argument_length(name)
|
135
|
+
definition(name)[:arguments]
|
136
|
+
end # def arguments(name)
|
137
|
+
|
138
|
+
def value(name)
|
139
|
+
definition(name)[:value]
|
140
|
+
end # def value(name)
|
141
|
+
|
142
|
+
def set_value(name, given_value)
|
143
|
+
hash = select { |h| h[:short] == name || h[:long] == name }[0]
|
144
|
+
raise(ArgumentError.new("option with #{name} could not be found")) if hash.nil?
|
145
|
+
@options[index(hash)] = hash.merge(:value => given_value) # [index(hash)]= gives you a syntax error
|
146
|
+
end # def set_value(name, given_value)
|
147
|
+
|
148
|
+
# shows help message to STDOUT
|
149
|
+
def help
|
150
|
+
STDERR.puts("USAGE: #{$0}")
|
151
|
+
|
152
|
+
@options.each do |o|
|
153
|
+
|
154
|
+
temp = ''
|
155
|
+
|
156
|
+
o[:short] ? temp << "-#{o[:short]}" : temp << "\t"
|
157
|
+
temp.length > 0 ? temp << ", " : temp << "\t"
|
158
|
+
o[:long] ? temp << "--#{o[:long]}" : temp << "\t"
|
159
|
+
|
160
|
+
temp << "\t\t"
|
161
|
+
temp << o[:description]
|
162
|
+
|
163
|
+
if o[:description]
|
164
|
+
temp << ' '
|
165
|
+
end
|
166
|
+
|
167
|
+
case o[:arguments]
|
168
|
+
when :all
|
169
|
+
temp << "(multiple arguments)"
|
170
|
+
when 0
|
171
|
+
temp << "(boolean)"
|
172
|
+
when 1
|
173
|
+
temp << "(1 argument)"
|
174
|
+
else
|
175
|
+
temp << "(#{o[:arguments]} arguments)"
|
176
|
+
end
|
177
|
+
puts temp
|
178
|
+
|
179
|
+
end # @options.each do |o|
|
180
|
+
|
181
|
+
nil
|
182
|
+
end # def help
|
183
|
+
|
184
|
+
def option(name, opts = {}, &block)
|
185
|
+
@queue = {
|
186
|
+
:short => opts[:short], # without hyphens
|
187
|
+
:long => opts[:long], # this too
|
188
|
+
:description => '',
|
189
|
+
:arguments => :all, # Integer, :all
|
190
|
+
:action => nil, # a Proc object, rarity should be :arguments, use *args if :all.
|
191
|
+
:priority => :option # priority, :option first then :runner. only one :runner should be called at a time.
|
192
|
+
} # defaults
|
193
|
+
|
194
|
+
if name.length > 1
|
195
|
+
@queue[:long] = name
|
196
|
+
else
|
197
|
+
@queue[:short] = name
|
198
|
+
end
|
199
|
+
|
200
|
+
instance_eval(&block) if block_given?
|
201
|
+
|
202
|
+
flush!
|
203
|
+
end
|
204
|
+
|
205
|
+
private
|
206
|
+
|
207
|
+
# flushes @queue into @commands array, used to implement DSL.
|
208
|
+
def flush!
|
209
|
+
return nil if @queue.empty?
|
210
|
+
|
211
|
+
self << @queue
|
212
|
+
@queue = {}
|
213
|
+
self[-1]
|
214
|
+
end
|
215
|
+
|
216
|
+
def describe(desc = '', opts = {})
|
217
|
+
@queue[:description] = desc
|
218
|
+
end
|
219
|
+
|
220
|
+
# Integer or :all (= default), defaults are set in #option method
|
221
|
+
def arguments(n, opts = {})
|
222
|
+
@queue[:arguments] = n
|
223
|
+
end
|
224
|
+
|
225
|
+
def action(opts = {}, &block)
|
226
|
+
@queue[:action] = block
|
227
|
+
end
|
228
|
+
|
229
|
+
# sets priority for the option, default is :option.
|
230
|
+
def priority(type)
|
231
|
+
raise(ArgumentError.new("priority must be :option or :runner but :#{type} given.")) unless [:option, :runner].include?(type)
|
232
|
+
@queue[:priority] = type
|
233
|
+
end # def priority(type)
|
234
|
+
|
235
|
+
def default(name)
|
236
|
+
@default = name
|
237
|
+
end
|
238
|
+
|
239
|
+
class << self
|
240
|
+
|
241
|
+
# Commands.define do
|
242
|
+
# option 'run', :short => 'S' do
|
243
|
+
# action do ||
|
244
|
+
# end
|
245
|
+
# end
|
246
|
+
def define(opts = {}, &block)
|
247
|
+
raise(ArgumentError.new('no block given')) unless block_given?
|
248
|
+
|
249
|
+
c = Commands.new(opts)
|
250
|
+
c.instance_eval(&block)
|
251
|
+
|
252
|
+
c
|
253
|
+
end
|
254
|
+
|
255
|
+
end
|
256
|
+
|
257
|
+
end # class Commands
|
258
|
+
|
259
|
+
end # module ArgumentSensei
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,202 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class ArgumentSenseiTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
Commands = ArgumentSensei::Commands
|
6
|
+
|
7
|
+
context 'Commands' do
|
8
|
+
|
9
|
+
should 'parses accordingly with defined options' do
|
10
|
+
|
11
|
+
c = Commands.define(:arguments => %w(orphan1 -S short1 short2 orphan2 --long1 long1 long2 long3 --long2 long4 long5 orphan3 --boolean)) do
|
12
|
+
option 'S' do
|
13
|
+
arguments 2
|
14
|
+
end
|
15
|
+
option 'long1'
|
16
|
+
option 'long2', :short => 'L' do
|
17
|
+
arguments 2
|
18
|
+
describe 'takes long4 and long5 then leaves orphan3'
|
19
|
+
end
|
20
|
+
option 'boolean' do
|
21
|
+
arguments 0
|
22
|
+
end
|
23
|
+
end # c = Commands.define do
|
24
|
+
|
25
|
+
assert_equal({
|
26
|
+
:orphans => %w(orphan1 orphan2 orphan3),
|
27
|
+
'S' => %w(short1 short2),
|
28
|
+
'long1' => %w(long1 long2 long3),
|
29
|
+
'long2' => %w(long4 long5),
|
30
|
+
'L' => %w(long4 long5),
|
31
|
+
'boolean' => true
|
32
|
+
}, c.parse)
|
33
|
+
|
34
|
+
c = Commands.define(:arguments => %w(--what if there --are nothing defined)) do
|
35
|
+
end
|
36
|
+
|
37
|
+
assert_nothing_raised { c.parse.inspect }
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
should 'parses combined short boolean switches' do
|
42
|
+
# -abcDEF => -a -b -c -D -E -F, as long as they are boolean.
|
43
|
+
# if non-booleans included, returns error,
|
44
|
+
# unknowns will just be ignored.
|
45
|
+
c = Commands.define(:arguments => %w(-aBC -A forA)) do
|
46
|
+
option 'a' do
|
47
|
+
arguments 0
|
48
|
+
end
|
49
|
+
option 'B' do
|
50
|
+
arguments 0
|
51
|
+
end
|
52
|
+
option 'C' do
|
53
|
+
arguments 0
|
54
|
+
end
|
55
|
+
option 'A' do
|
56
|
+
arguments 1
|
57
|
+
end
|
58
|
+
end.parse # c = Commands.define(:arguments => %w()) do
|
59
|
+
assert(c['a'])
|
60
|
+
assert(c['B'])
|
61
|
+
assert(c['C'])
|
62
|
+
assert_equal(['forA'], c['A'])
|
63
|
+
|
64
|
+
# non boolean should not be combined.
|
65
|
+
assert_raise(ArgumentError) do
|
66
|
+
c = Commands.define(:arguments => %w(-aB)) do
|
67
|
+
option 'a' do
|
68
|
+
arguments 0
|
69
|
+
end
|
70
|
+
option 'B' do
|
71
|
+
arguments :all
|
72
|
+
end
|
73
|
+
end.parse
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
should 'runs given actions' do
|
78
|
+
done = false
|
79
|
+
should_not_do = true
|
80
|
+
Commands.define(:arguments => %w(--do)) do
|
81
|
+
option 'do' do
|
82
|
+
action do
|
83
|
+
done = true
|
84
|
+
end
|
85
|
+
end
|
86
|
+
option 'do not' do
|
87
|
+
action do
|
88
|
+
should_not_do = false
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end.run! # c = Commands.define do
|
92
|
+
assert(done, 'action were not called')
|
93
|
+
assert(should_not_do, 'even other action got run')
|
94
|
+
end
|
95
|
+
|
96
|
+
should 'runs default action' do
|
97
|
+
done = false
|
98
|
+
Commands.define do
|
99
|
+
option 'D' do
|
100
|
+
action do
|
101
|
+
done = true
|
102
|
+
end
|
103
|
+
end
|
104
|
+
default 'D'
|
105
|
+
end.run!
|
106
|
+
assert(done, 'default action was not called')
|
107
|
+
end
|
108
|
+
|
109
|
+
should 'should not raise any error for undefined options' do
|
110
|
+
assert_nothing_raised(Exception) do
|
111
|
+
Commands.define(:arguments => %w(-these -commands --are not defined --yet)) do
|
112
|
+
option 't' do
|
113
|
+
arguments 0
|
114
|
+
end
|
115
|
+
option 'o' do
|
116
|
+
arguments 0
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'Prioritization' do
|
123
|
+
|
124
|
+
should 'should be defined as option' do
|
125
|
+
assert_equal(:option, Commands.define { option('-t') { priority :option } }.options[0][:priority])
|
126
|
+
end
|
127
|
+
|
128
|
+
should 'should be defined as runner' do
|
129
|
+
assert_equal(:runner, Commands.define { option('-t') { priority :runner } }.options[0][:priority])
|
130
|
+
end
|
131
|
+
|
132
|
+
should 'runs options first then a runner' do
|
133
|
+
first = false; last = false
|
134
|
+
was_first_last = false
|
135
|
+
was_last_first = false
|
136
|
+
|
137
|
+
assert_nothing_raised(Exception) do
|
138
|
+
Commands.define(:arguments => %w(-l -f)) do
|
139
|
+
option 'l' do
|
140
|
+
priority :runner
|
141
|
+
action do
|
142
|
+
|
143
|
+
last = true
|
144
|
+
was_last_first = true unless first
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|
148
|
+
option 'f' do
|
149
|
+
priority :option
|
150
|
+
action do
|
151
|
+
|
152
|
+
first = true
|
153
|
+
was_first_last = true if last
|
154
|
+
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end.run!
|
158
|
+
end
|
159
|
+
|
160
|
+
assert(!was_last_first, 'Runner ran first.')
|
161
|
+
assert(!was_first_last, 'Option ran last.')
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
should 'should not accept multiple runners at a time' do
|
166
|
+
shouldnotrun1 = false
|
167
|
+
shouldnotrun2 = false
|
168
|
+
assert_raise(RuntimeError) do
|
169
|
+
Commands.define(:arguments => %w(-a -b)) do
|
170
|
+
option 'a' do
|
171
|
+
priority :runner
|
172
|
+
action do
|
173
|
+
shouldnotrun1 = true
|
174
|
+
end
|
175
|
+
end
|
176
|
+
option 'b' do
|
177
|
+
priority :runner
|
178
|
+
action do
|
179
|
+
shouldnotrun2 = true
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end.run!
|
183
|
+
end
|
184
|
+
assert(!shouldnotrun1)
|
185
|
+
assert(!shouldnotrun2)
|
186
|
+
end
|
187
|
+
|
188
|
+
end # context 'Priority' do
|
189
|
+
|
190
|
+
end # context 'Commands' do
|
191
|
+
|
192
|
+
context 'ArgumentSensei' do
|
193
|
+
|
194
|
+
context 'Class' do
|
195
|
+
end # Class
|
196
|
+
|
197
|
+
context 'Instance' do
|
198
|
+
end # Instance
|
199
|
+
|
200
|
+
end # ArgumentSensei
|
201
|
+
|
202
|
+
end # class ArgumentSenseiTest < Test::Unit::TestCase
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hirobumi-argument_sensei
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Hirobumi Hama
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-10 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: hama@yoidore.org
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
files:
|
25
|
+
- README.rdoc
|
26
|
+
- Rakefile
|
27
|
+
- lib/argument_sensei
|
28
|
+
- lib/argument_sensei/commands.rb
|
29
|
+
- lib/argument_sensei/version.rb
|
30
|
+
- lib/argument_sensei.rb
|
31
|
+
- test/test_helper.rb
|
32
|
+
- test/unit
|
33
|
+
- test/unit/argument_sensei_test.rb
|
34
|
+
has_rdoc: true
|
35
|
+
homepage: http://yoidore.org/argument_sensei
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options:
|
38
|
+
- --main
|
39
|
+
- README.rdoc
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
version:
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: "0"
|
53
|
+
version:
|
54
|
+
requirements: []
|
55
|
+
|
56
|
+
rubyforge_project:
|
57
|
+
rubygems_version: 1.2.0
|
58
|
+
signing_key:
|
59
|
+
specification_version: 2
|
60
|
+
summary: ArgumentSensei is yet another command-line argument parser with a minimal set of features.
|
61
|
+
test_files: []
|
62
|
+
|