main 4.3.0 → 4.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -450,6 +450,48 @@ SAMPLES
450
450
  "forty-two"
451
451
 
452
452
 
453
+ <========< samples/j.rb >========>
454
+
455
+ ~ > cat samples/j.rb
456
+
457
+ #!/usr/bin/env ruby
458
+
459
+ require 'open-uri'
460
+
461
+ require 'main'
462
+ require 'digest/sha2'
463
+
464
+ # you have access to a sequel/amalgalite/sqlite db for free
465
+ #
466
+
467
+ Main {
468
+ name :i_can_haz_db
469
+
470
+ db {
471
+ create_table(:mp3s) do
472
+ primary_key :id
473
+ String :url
474
+ String :sha
475
+ end unless table_exists?(:mp3s)
476
+ }
477
+
478
+ def run
479
+ url = 'http://s3.amazonaws.com/drawohara.com.mp3/ween-voodoo_lady.mp3'
480
+ mp3 = open(url){|fd| fd.read}
481
+ sha = Digest::SHA2.hexdigest(mp3)
482
+
483
+ db[:mp3s].insert(:url => url, :sha => sha)
484
+ p db[:mp3s].all
485
+ p db
486
+ end
487
+ }
488
+
489
+ ~ > ruby samples/j.rb
490
+
491
+ [{:url=>"http://s3.amazonaws.com/drawohara.com.mp3/ween-voodoo_lady.mp3", :sha=>"54c99ac7588dcfce1e70540b734805e9c69ff98dcca001e6f2bdec140fb0f9dc", :id=>1}, {:url=>"http://s3.amazonaws.com/drawohara.com.mp3/ween-voodoo_lady.mp3", :sha=>"54c99ac7588dcfce1e70540b734805e9c69ff98dcca001e6f2bdec140fb0f9dc", :id=>2}]
492
+ #<Sequel::Amalgalite::Database: "amalgalite://Users/ahoward/.i_can_haz_db/db.sqlite">
493
+
494
+
453
495
 
454
496
  DOCS
455
497
  test/main.rb
@@ -457,6 +499,69 @@ DOCS
457
499
  API section below
458
500
 
459
501
  HISTORY
502
+ 4.4.0
503
+ - support for automatic sequel/sqlite/amalgalite dbs for persistent state
504
+ across invocations
505
+
506
+ Main {
507
+ db {
508
+ create_table :foo do
509
+ String key
510
+ String val
511
+ end unless table_exists? :foo
512
+ }
513
+
514
+ def run
515
+ db[:foo].create(:key => 'using', :val => 'amalgalite')
516
+ end
517
+ }
518
+
519
+ - support for automatic config files with auto populated template data
520
+
521
+ Main {
522
+ config :email => 'your.addy@gmail.com', :password => 'pa$$word'
523
+
524
+ def run
525
+ email = config[:email]
526
+ end
527
+ }
528
+
529
+ - new paramter types :pathname, :path, :slug, :input, and :output
530
+
531
+ - input/output parameters. can be filenames or '-' to supply
532
+ stdin/stdout respectively
533
+
534
+ Main {
535
+ input :i
536
+ output :o
537
+
538
+ def run
539
+ i = params[:i].value
540
+ o = params[:o].value
541
+
542
+ line = i.gets
543
+ o.puts line
544
+ end
545
+ }
546
+
547
+ - clean up warnings running with 'ruby -w'
548
+
549
+ - fix a failing test
550
+
551
+ - ability to ignore parameters in sub modes
552
+
553
+ Main {
554
+ argument :foo
555
+ argument :bar
556
+
557
+ def run
558
+ p param[:bar].value
559
+ end
560
+
561
+ mode :ignoring do
562
+ params[:foo].ignore!
563
+ end
564
+ }
460
565
  4.0.0
461
566
  - avoid duping ios. new methods Main.push_ios! and Main.pop_ios! are
462
567
  utilized for testing. this was done to make it simple to wrap
data/README.erb CHANGED
@@ -5,9 +5,9 @@ SYNOPSIS
5
5
  a class factory and dsl for generating command line programs real quick
6
6
 
7
7
  URI
8
+ http://github.com/ahoward/main
8
9
  http://codeforpeople.com/lib/ruby/
9
10
  http://rubyforge.org/projects/codeforpeople/
10
- http://github.com/ahoward/main
11
11
 
12
12
  INSTALL
13
13
  gem install main
@@ -26,6 +26,8 @@ DESCRIPTION
26
26
  - parsing user defined ARGV and ENV
27
27
  - zero requirements for understanding the obtuse apis of *any* command
28
28
  line option parsers
29
+ - built-in support for persistent state via sqlite/sequel/amalgalite
30
+ - built-in support for yaml config files
29
31
  - leather pants
30
32
 
31
33
  in short main.rb aims to drastically lower the barrier to writing uniform
@@ -186,6 +188,82 @@ DOCS
186
188
  API section below
187
189
 
188
190
  HISTORY
191
+ 4.4.0
192
+ - app storage under a dotdir. for example
193
+
194
+ Main {
195
+ name :foobar
196
+ }
197
+
198
+ will have a ~/.foobar/ directory available for storing db/config/etc.
199
+
200
+ - support for automatic sequel/sqlite/amalgalite dbs for persistent state
201
+ across invocations. the db is automatically created under the main
202
+ programs dotdir (~/.$appname/db.sqlite)
203
+
204
+ Main {
205
+ db {
206
+ create_table :foo do
207
+ String key
208
+ String val
209
+ end unless table_exists? :foo
210
+ }
211
+
212
+ def run
213
+ db[:foo].create(:key => 'using', :val => 'amalgalite')
214
+ end
215
+ }
216
+
217
+ - support for automatic config files with auto populated template data.
218
+ the first time the program is run the user's editor will be invoked on a
219
+ config file pre-populate with the same config. subsequent invocations
220
+ will use the user configured values. the config file is stored at
221
+ ~/.$appname/config.yml
222
+
223
+ Main {
224
+ config :email => 'your.addy@gmail.com', :password => 'pa$$word'
225
+
226
+ def run
227
+ email = config[:email]
228
+ end
229
+ }
230
+
231
+ - new paramter types :pathname, :path, :slug, :input, and :output
232
+
233
+ - input/output parameters. can be filenames or '-' to supply
234
+ stdin/stdout respectively
235
+
236
+ Main {
237
+ input :i
238
+ output :o
239
+
240
+ def run
241
+ i = params[:i].value
242
+ o = params[:o].value
243
+
244
+ line = i.gets
245
+ o.puts line
246
+ end
247
+ }
248
+
249
+ - clean up warnings running with 'ruby -w'
250
+
251
+ - fix a failing test
252
+
253
+ - ability to ignore parameters in sub modes
254
+
255
+ Main {
256
+ argument :foo
257
+ argument :bar
258
+
259
+ def run
260
+ p param[:bar].value
261
+ end
262
+
263
+ mode :ignoring do
264
+ params[:foo].ignore!
265
+ end
266
+ }
189
267
  4.0.0
190
268
  - avoid duping ios. new methods Main.push_ios! and Main.pop_ios! are
191
269
  utilized for testing. this was done to make it simple to wrap
data/TODO CHANGED
@@ -1,20 +1,18 @@
1
+ todo:
2
+ - examples of new features
3
+ - use map.rb
1
4
 
2
- * support pathname casts
3
- * support uri casts
4
- * support filename casts
5
- * support directory costs
6
- * support io cast '-' (:input, :output)
7
-
8
- * fix weird super bug jeremy found
9
-
10
- * figure out how to support '-' ??
11
-
12
- * clean up warnings under 'ruby -w'
13
- * error reporting weird for some errors
14
-
15
- ===============================================================================
16
- X calls to abort sometimes lead to STDERR prining twice ;-(
17
- X main's' with modes, but no run do not operate properly - add default run w/wrap_run!
18
- X usage fubar when extra chunks are set
19
- X usage of arguments is fubar when negative arities are used
20
- X add sanity checks at parameter contruction completion
5
+ done:
6
+ - clean up warnings under 'ruby -w'
7
+ - intput/output arguments
8
+ - support io cast '-' (:input, :output)
9
+ - slug casts
10
+ - support uri casts
11
+ - dotdir support (based on name)
12
+ - db support
13
+ - configuration/configfile file support
14
+ - calls to abort sometimes lead to STDERR prining twice ;-(
15
+ - main's' with modes, but no run do not operate properly - add default run w/wrap_run!
16
+ - usage fubar when extra chunks are set
17
+ - usage of arguments is fubar when negative arities are used
18
+ - add sanity checks at parameter contruction completion
data/a.rb CHANGED
@@ -1,6 +1,33 @@
1
1
  require 'main'
2
2
 
3
3
  Main {
4
- argument('zero_or_more'){ arity(-1) }
5
- run{ p params }
4
+
5
+ name :foobar
6
+
7
+ db {
8
+ create_table(:foo) do
9
+ primary_key :id
10
+ String :name
11
+ Float :price
12
+ end unless table_exists?(:foo)
13
+ }
14
+
15
+ config(
16
+ :email => 'your.addy@gmail.com',
17
+ :password => 'yourPa$$word'
18
+ )
19
+
20
+ io
21
+
22
+
23
+ def run
24
+ #p input.path
25
+ #p output.path
26
+ p params.map{|param| param.name}
27
+ output.puts(:foobar)
28
+ end
29
+
30
+ mode :foo do
31
+ params[:input].ignore!
32
+ end
6
33
  }
data/lib/main.rb CHANGED
@@ -2,7 +2,7 @@ module Main
2
2
  #
3
3
  # top level constants
4
4
  #
5
- Main::VERSION = '4.3.0' unless
5
+ Main::VERSION = '4.4.0' unless
6
6
  defined? Main::VERSION
7
7
  def self.version() Main::VERSION end
8
8
 
@@ -13,6 +13,7 @@ module Main
13
13
  Main::EXIT_SUCCESS = 0 unless defined? Main::EXIT_SUCCESS
14
14
  Main::EXIT_FAILURE = 1 unless defined? Main::EXIT_FAILURE
15
15
  Main::EXIT_WARN = 42 unless defined? Main::EXIT_WARN
16
+ Main::EXIT_WARNING = 42 unless defined? Main::EXIT_WARNING
16
17
  #
17
18
  # built-in
18
19
  #
data/lib/main/cast.rb CHANGED
@@ -25,7 +25,7 @@ module Main
25
25
  end
26
26
 
27
27
  cast :integer do |obj|
28
- Integer obj
28
+ Float(obj).to_i
29
29
  end
30
30
 
31
31
  cast :float do |obj|
@@ -45,7 +45,7 @@ module Main
45
45
  end
46
46
 
47
47
  cast :uri do |obj|
48
- require 'uri'
48
+ require 'uri' unless defined?(::URI)
49
49
  ::URI.parse obj.to_s
50
50
  end
51
51
 
@@ -55,10 +55,53 @@ module Main
55
55
  end
56
56
 
57
57
  cast :date do |obj|
58
- require 'date'
58
+ require 'date' unless defined?(::Date)
59
59
  ::Date.parse obj.to_s
60
60
  end
61
61
 
62
+ cast :pathname do |obj|
63
+ require 'pathname' unless defined?(::Pathname)
64
+ Pathname.new(obj.to_s)
65
+ end
66
+
67
+ cast :path do |obj|
68
+ File.expand_path(obj.to_s)
69
+ end
70
+
71
+ cast :input do |obj|
72
+ case obj.to_s
73
+ when '-'
74
+ io = STDIN.dup
75
+ io.fattr(:path){ '/dev/stdin' }
76
+ io
77
+ else
78
+ io = open(obj.to_s, 'r+')
79
+ at_exit{ io.close }
80
+ io
81
+ end
82
+ end
83
+
84
+ cast :output do |obj|
85
+ case obj.to_s
86
+ when '-'
87
+ io = STDOUT.dup
88
+ io.fattr(:path){ '/dev/stdout' }
89
+ io
90
+ else
91
+ io = open(obj.to_s, 'w+')
92
+ at_exit{ io.close }
93
+ io
94
+ end
95
+ end
96
+
97
+ cast :slug do |obj|
98
+ string = [obj].flatten.compact.join('-')
99
+ words = string.to_s.scan(%r/\w+/)
100
+ words.map!{|word| word.gsub %r/[^0-9a-zA-Z_-]/, ''}
101
+ words.delete_if{|word| word.nil? or word.strip.empty?}
102
+ String(words.join('-').downcase)
103
+ end
104
+
62
105
  cast :list do |*objs|
63
106
  [*objs].flatten.join(',').split(/,/)
64
107
  end
@@ -109,10 +109,15 @@ module Main
109
109
  names.first
110
110
  end
111
111
 
112
- def default
112
+ def default(*values)
113
+ defaults(values) unless values.empty?
113
114
  defaults.first
114
115
  end
115
116
 
117
+ def default=(value)
118
+ default(value)
119
+ end
120
+
116
121
  def typename
117
122
  prefix = '--' if type.to_s =~ %r/option/
118
123
  "#{ type }(#{ prefix }#{ name })"
@@ -248,6 +253,13 @@ module Main
248
253
  end
249
254
  end
250
255
 
256
+ def remove
257
+ main.parameters.delete(self)
258
+ end
259
+ alias_method('remove!', 'remove')
260
+ alias_method('ignore', 'remove')
261
+ alias_method('ignore!', 'ignore')
262
+
251
263
  class Argument < Parameter
252
264
  fattr 'required' => true
253
265
 
@@ -527,6 +539,15 @@ module Main
527
539
  delete(*a)
528
540
  super
529
541
  end
542
+
543
+ def [](*index)
544
+ first = index.first
545
+ if(index.size == 1 and (first.is_a?(String) or first.is_a?(Symbol)))
546
+ first = first.to_s
547
+ return detect{|param| param.name == first}
548
+ end
549
+ return super
550
+ end
530
551
  end
531
552
 
532
553
  class DSL
@@ -21,11 +21,11 @@ module Main
21
21
  fattr('exit_success'){ Main::EXIT_SUCCESS }
22
22
  fattr('exit_failure'){ Main::EXIT_FAILURE }
23
23
  fattr('exit_warn'){ Main::EXIT_WARN }
24
+ fattr('exit_warning'){ Main::EXIT_WARNING }
24
25
  fattr('parameters'){ Main::Parameter::List[] }
25
26
  fattr('can_has_hash'){ Hash.new }
26
27
  fattr('mixin_table'){ Hash.new }
27
28
 
28
- fattr('factory')
29
29
  fattr('argv')
30
30
  fattr('env')
31
31
  fattr('opts')
@@ -35,6 +35,10 @@ module Main
35
35
  end
36
36
  alias_method 'create', 'factory'
37
37
 
38
+ def factory=(factory)
39
+ @factory = factory
40
+ end
41
+
38
42
  class Factory
39
43
  def initialize(&block)
40
44
  @block = block || lambda{}
@@ -84,6 +88,10 @@ module Main
84
88
  instance
85
89
  end
86
90
 
91
+ def params
92
+ parameters
93
+ end
94
+
87
95
  def evaluate(&block)
88
96
  module_eval(&block)
89
97
  end
@@ -182,23 +190,23 @@ module Main
182
190
  end
183
191
 
184
192
  def parameter(*a, &b)
185
- (parameters << Parameter.create(:parameter, self, *a, &b)).last
193
+ (parameters << Parameter.create(:parameter, main=self, *a, &b)).last
186
194
  end
187
195
 
188
196
  def argument(*a, &b)
189
- (parameters << Parameter.create(:argument, self, *a, &b)).last
197
+ (parameters << Parameter.create(:argument, main=self, *a, &b)).last
190
198
  end
191
199
 
192
200
  def option(*a, &b)
193
- (parameters << Parameter.create(:option, self, *a, &b)).last
201
+ (parameters << Parameter.create(:option, main=self, *a, &b)).last
194
202
  end
195
203
 
196
204
  def keyword(*a, &b)
197
- (parameters << Parameter.create(:keyword, self, *a, &b)).last
205
+ (parameters << Parameter.create(:keyword, main=self, *a, &b)).last
198
206
  end
199
207
 
200
208
  def environment(*a, &b)
201
- (parameters << Parameter.create(:environment, self, *a, &b)).last
209
+ (parameters << Parameter.create(:environment, main=self, *a, &b)).last
202
210
  end
203
211
 
204
212
  def default_options!
@@ -259,6 +267,86 @@ module Main
259
267
  block ||= lambda{}
260
268
  define_method(:run, &block) if block
261
269
  end
270
+
271
+ def dotdir(*dotdir, &block)
272
+ @dotdir = File.join(Util.home, ".#{ name }") unless defined?(@dotdir)
273
+
274
+ @dotdir = dotdir.join('/') unless dotdir.empty?
275
+
276
+ if block
277
+ require 'fileutils' unless defined?(FileUtils)
278
+ FileUtils.mkdir_p(@dotdir) unless test(?d, @dotdir)
279
+ Dir.chdir(&block)
280
+ else
281
+ @dotdir
282
+ end
283
+ end
284
+
285
+ def db(*args, &block)
286
+ unless defined?(@db)
287
+ require 'sequel' unless defined?(Sequel)
288
+ require 'amalgalite' unless defined?(Amalgalite)
289
+ @db = dotdir{ Sequel.amalgalite(db_path) }
290
+ @db.instance_eval(&block) if block
291
+ end
292
+ @db
293
+ end
294
+
295
+ def db_path(*db_path)
296
+ @db_path = File.join(dotdir, 'db.sqlite') unless defined?(@db_path)
297
+ @db_path = File.join(*db_path) unless db_path.empty?
298
+ @db_path
299
+ end
300
+
301
+ def config(*args, &block)
302
+ unless defined?(@config)
303
+ require 'yaml' unless defined?(YAML)
304
+ if test(?s, config_path)
305
+ @config = YAML.load(IO.read(config_path))
306
+ else
307
+ config = args.last.is_a?(Hash) ? args.last : {}
308
+ lines = config.to_yaml.split(/\n/)
309
+ dash = lines.shift
310
+ open(config_path, 'w') do |fd|
311
+ fd.puts '### you may need to edit this config!'
312
+ fd.puts
313
+ fd.puts lines
314
+ end
315
+ editor = ENV['EDITOR'] || ENV['EDIT'] || 'vi'
316
+ system("#{ editor.inspect } #{ config_path }")
317
+ @config = YAML.load(IO.read(config_path))
318
+ end
319
+ end
320
+ @config
321
+ end
322
+
323
+ def config_path(*config_path)
324
+ @config_path = File.join(dotdir, 'config.yml') unless defined?(@config_path)
325
+ @config_path = File.join(*config_path) unless config_path.empty?
326
+ @config_path
327
+ end
328
+
329
+ def input(*args, &block)
330
+ first = args.first
331
+ args.push(:input) unless(first.is_a?(Symbol) or first.is_a?(String))
332
+ param = argument(*args, &block)
333
+ param.cast(:input)
334
+ param
335
+ end
336
+
337
+ def output(*args, &block)
338
+ first = args.first
339
+ args.push(:output) unless(first.is_a?(Symbol) or first.is_a?(String))
340
+ param = argument(*args, &block)
341
+ param.cast(:output)
342
+ param
343
+ end
344
+
345
+ def io(*args)
346
+ i = input(*[args.shift].compact).default('-')
347
+ o = output(*[args.shift].compact).default('-')
348
+ [i, o]
349
+ end
262
350
  end
263
351
 
264
352
  extend ClassMethods
@@ -16,7 +16,7 @@ module Main
16
16
 
17
17
  %w(
18
18
  program name synopsis description author version
19
- exit_status exit_success exit_failure exit_warn
19
+ exit_status exit_success exit_failure exit_warn exit_warning
20
20
  logger_level
21
21
  usage
22
22
  ).each{|a| fattr(a){ self.class.send a}}
@@ -31,9 +31,9 @@ module Main
31
31
  end
32
32
 
33
33
  %w( debug info warn fatal error ).each do |m|
34
- module_eval <<-code
35
- def #{ m } *a, &b
36
- logger.#{ m } *a, &b
34
+ module_eval <<-code, __FILE__, __LINE__
35
+ def #{ m }(*a, &b)
36
+ logger.#{ m }(*a, &b)
37
37
  end
38
38
  code
39
39
  end
@@ -87,7 +87,6 @@ module Main
87
87
  end
88
88
 
89
89
  def setup_io_restoration
90
- return
91
90
  @finalizers ||= []
92
91
  [STDIN, STDOUT, STDERR].each do |io|
93
92
  dup = io.dup
@@ -250,9 +249,9 @@ module Main
250
249
  end
251
250
 
252
251
  %w[ before instead after ].each do |which|
253
- module_eval <<-code
254
- def error_handler_#{ which } *argv, &block
255
- block.call *argv
252
+ module_eval <<-code, __FILE__, __LINE__
253
+ def error_handler_#{ which }(*argv, &block)
254
+ block.call(*argv)
256
255
  end
257
256
  code
258
257
  end
@@ -265,6 +264,26 @@ module Main
265
264
  singleton_class.module_eval{ define_method('__instance_eval_block', &block) }
266
265
  fcall(self, '__instance_eval_block', *argv, &block)
267
266
  end
267
+
268
+ def dotdir(&block)
269
+ self.class.dotdir(&block)
270
+ end
271
+
272
+ def db(&block)
273
+ self.class.db(&block)
274
+ end
275
+
276
+ def config(&block)
277
+ self.class.config(&block)
278
+ end
279
+
280
+ def input
281
+ @input ||= params[:input].value if params[:input]
282
+ end
283
+
284
+ def output
285
+ @output ||= params[:output].value if params[:output]
286
+ end
268
287
  end
269
288
 
270
289
  include InstanceMethods
data/lib/main/util.rb CHANGED
@@ -71,6 +71,20 @@ module Main
71
71
 
72
72
  return default
73
73
  end
74
+
75
+ def home
76
+ home =
77
+ catch :home do
78
+ ["HOME", "USERPROFILE"].each do |key|
79
+ throw(:home, ENV[key]) if ENV[key]
80
+ end
81
+ if ENV["HOMEDRIVE"] and ENV["HOMEPATH"]
82
+ throw(:home, "#{ ENV['HOMEDRIVE'] }:#{ ENV['HOMEPATH'] }")
83
+ end
84
+ File.expand_path("~") rescue(File::ALT_SEPARATOR ? "C:/" : "/")
85
+ end
86
+ File.expand_path(home)
87
+ end
74
88
  end
75
89
 
76
90
  BLESS = lambda do |other|
data/main.gemspec CHANGED
@@ -4,7 +4,7 @@
4
4
  Gem::Specification::new do |spec|
5
5
  spec.name = "main"
6
6
  spec.description = 'a class factory and dsl for generating command line programs real quick'
7
- spec.version = "4.3.0"
7
+ spec.version = "4.4.0"
8
8
  spec.platform = Gem::Platform::RUBY
9
9
  spec.summary = "main"
10
10
 
data/samples/j.rb CHANGED
@@ -1,14 +1,31 @@
1
1
  #!/usr/bin/env ruby
2
+
3
+ require 'open-uri'
4
+
2
5
  require 'main'
6
+ require 'digest/sha2'
7
+
8
+ # you have access to a sequel/amalgalite/sqlite db for free
9
+ #
3
10
 
4
11
  Main {
5
- mode( :foo ) {
6
- argument( :bar ) {
7
- required
8
- default 42
9
- }
10
- run {
11
- puts "Doing something with #{params['bar'].value}"
12
- }
12
+ name :i_can_haz_db
13
+
14
+ db {
15
+ create_table(:mp3s) do
16
+ primary_key :id
17
+ String :url
18
+ String :sha
19
+ end unless table_exists?(:mp3s)
13
20
  }
21
+
22
+ def run
23
+ url = 'http://s3.amazonaws.com/drawohara.com.mp3/ween-voodoo_lady.mp3'
24
+ mp3 = open(url){|fd| fd.read}
25
+ sha = Digest::SHA2.hexdigest(mp3)
26
+
27
+ db[:mp3s].insert(:url => url, :sha => sha)
28
+ p db[:mp3s].all
29
+ p db
30
+ end
14
31
  }
data/test/main.rb CHANGED
@@ -258,7 +258,7 @@ class T < Test::Unit::TestCase
258
258
  }
259
259
  option('y'){
260
260
  argument_required
261
- process{|*values| values.join.split(',').map{|value| value.upcase}}
261
+ cast{|*values| values.join.split(',').map{|value| value.upcase}}
262
262
  }
263
263
  define_method('run'){ param = params }
264
264
  }
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: main
3
3
  version: !ruby/object:Gem::Version
4
- hash: 51
4
+ hash: 47
5
5
  prerelease: false
6
6
  segments:
7
7
  - 4
8
- - 3
8
+ - 4
9
9
  - 0
10
- version: 4.3.0
10
+ version: 4.4.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ara T. Howard
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-07 01:00:00 -06:00
18
+ date: 2010-11-25 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency