abundance 1.2.4 → 1.2.5
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/abundance.rb +3 -3
- data/lib/garden.rb +1 -7
- data/lib/garden_cycles.rb +92 -93
- data/lib/gardener.rb +11 -9
- data/lib/{garden_rows.rb → rows.rb} +12 -25
- data/lib/rows_paths.rb +40 -0
- data/test/tc_high_api.rb +1 -1
- data/test/tc_multi_gardener.rb +2 -2
- metadata +4 -3
data/lib/abundance.rb
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
#
|
10
10
|
# And not:
|
11
11
|
# * a replacement for Thread.new invocations
|
12
|
-
# * a replacement for
|
12
|
+
# * a replacement for concurrent programming languages like Erlang
|
13
13
|
#
|
14
14
|
# Its initial implementation uses:
|
15
15
|
# * pure ruby
|
@@ -71,8 +71,8 @@ class Abundance
|
|
71
71
|
# id1 = gardener.seed('command1')
|
72
72
|
# id2 = gardener.seed('command2')
|
73
73
|
#
|
74
|
-
# result1 = gardener.harvest(id1)
|
75
|
-
# result2 = gardener.harvest(id2)
|
74
|
+
# result1 = gardener.harvest(:one,id1)
|
75
|
+
# result2 = gardener.harvest(:one,id2)
|
76
76
|
#
|
77
77
|
# # with many more seeds over here
|
78
78
|
#
|
data/lib/garden.rb
CHANGED
@@ -15,7 +15,7 @@
|
|
15
15
|
# :title:Garden
|
16
16
|
|
17
17
|
class Garden
|
18
|
-
require '
|
18
|
+
require 'rows'
|
19
19
|
require 'garden_cycles'
|
20
20
|
include Cycles
|
21
21
|
require 'toolshed'
|
@@ -52,12 +52,6 @@ class Garden
|
|
52
52
|
report_growth(message_block)
|
53
53
|
when :harvest
|
54
54
|
harvest_some(message_block)
|
55
|
-
when :init
|
56
|
-
ask_for_init_status(message_block)
|
57
|
-
when :init_crop
|
58
|
-
answer_init_status(message_block)
|
59
|
-
when :seed_all_crop
|
60
|
-
special_crop_seed_all(message_block)
|
61
55
|
when :close
|
62
56
|
close_all(message_block)
|
63
57
|
else
|
data/lib/garden_cycles.rb
CHANGED
@@ -1,43 +1,43 @@
|
|
1
1
|
class Garden
|
2
|
+
# The Cycles module is a set of method used by the Garden's fork.
|
3
|
+
# You will not need to use these methods unless you plan on refactoring the Garden.
|
4
|
+
#
|
2
5
|
# Author:: lp (mailto:lp@spiralix.org)
|
3
6
|
# Copyright:: 2008 Louis-Philippe Perron - Released under the terms of the MIT license
|
4
7
|
# :title:Cycles
|
5
8
|
module Cycles
|
6
9
|
|
7
10
|
def set_my_containers
|
8
|
-
@
|
9
|
-
@
|
10
|
-
@
|
11
|
+
@close_message_block = nil; @full_crop_message_block = nil
|
12
|
+
@init_message_block = nil; @seed_all_message_block = nil
|
13
|
+
@harvest_queue = []; @waiting_rows = []; @id = 0
|
14
|
+
@seeds = []; @sprouts = []; @crops = []
|
11
15
|
end
|
12
16
|
|
13
17
|
def seed_if_row_available
|
14
18
|
catch :fill_rows do
|
15
19
|
loop do
|
16
|
-
if
|
17
|
-
row_socket_path = @
|
18
|
-
unless @
|
20
|
+
if @seed_all_message_block && ! @waiting_rows.empty? && @seed_all_message_block[4][:row_done].size != @seed_all_message_block[1]
|
21
|
+
row_socket_path = @waiting_rows.shift
|
22
|
+
unless @seed_all_message_block[4][:row_done].include?( row_socket_path )
|
19
23
|
socket_send([:seed,:all,@seed_all_message_block[2],row_socket_path])
|
20
|
-
@
|
24
|
+
@seed_all_message_block[4][:row_done] << row_socket_path
|
21
25
|
else
|
22
|
-
@
|
26
|
+
@waiting_rows << row_socket_path
|
23
27
|
end
|
24
|
-
elsif
|
25
|
-
row_socket_path = @
|
26
|
-
unless @
|
28
|
+
elsif @init_message_block && ! @waiting_rows.empty? && @init_message_block[4][:row_done].size != @init_message_block[2]
|
29
|
+
row_socket_path = @waiting_rows.shift
|
30
|
+
unless @init_message_block[4][:row_done].include?( row_socket_path )
|
27
31
|
socket_send([:seed,:init,'init_status',row_socket_path])
|
28
|
-
@
|
32
|
+
@init_message_block[4][:row_done] << row_socket_path
|
29
33
|
else
|
30
|
-
@
|
34
|
+
@waiting_rows << row_socket_path
|
31
35
|
end
|
32
|
-
elsif ! @seeds.empty? && ! @
|
33
|
-
seed = @seeds.shift
|
34
|
-
|
35
|
-
|
36
|
-
socket_send([:seed,:
|
37
|
-
elsif @quit && ! @rows_socket_paths.empty?
|
38
|
-
seed = nil
|
39
|
-
row_socket_path = @rows_socket_paths.shift
|
40
|
-
socket_send([:seed,:quit,seed,row_socket_path])
|
36
|
+
elsif ! @seeds.empty? && ! @waiting_rows.empty?
|
37
|
+
seed = @seeds.shift; @sprouts[seed[:id]] = seed
|
38
|
+
socket_send([:seed,:sprout,seed,@waiting_rows.shift])
|
39
|
+
elsif @close_message_block && ! @waiting_rows.empty?
|
40
|
+
socket_send([:seed,:quit,nil,@waiting_rows.shift])
|
41
41
|
else
|
42
42
|
throw :fill_rows
|
43
43
|
end
|
@@ -49,23 +49,24 @@ class Garden
|
|
49
49
|
case message_block[1]
|
50
50
|
when :one
|
51
51
|
@id += 1; @seeds << {:id => @id , :seed => message_block[2]}
|
52
|
-
|
52
|
+
message_block[2] = @id; socket_send(message_block)
|
53
53
|
else
|
54
54
|
@seed_all_message_block = Array.new(message_block)
|
55
|
+
@seed_all_message_block[4] = {:row_done => [], :crops => []}
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
58
59
|
def this_row_is_available(message_block)
|
59
|
-
if @
|
60
|
+
if @close_message_block
|
60
61
|
message_block = [:row, :quit, nil, message_block[3]]
|
61
|
-
elsif
|
62
|
+
elsif @seed_all_message_block && @seed_all_message_block[4][:row_done].size != @seed_all_message_block[1] && ! @seed_all_message_block[4][:row_done].include?( message_block[3] )
|
62
63
|
message_block = [:row, :all, @seed_all_message_block[2], message_block[3]]
|
63
|
-
@
|
64
|
-
elsif
|
64
|
+
@seed_all_message_block[4][:row_done] << message_block[3]
|
65
|
+
elsif @init_message_block && @init_message_block[4][:row_done].size != @init_message_block[2] && ! @init_message_block[4][:row_done].include?( message_block[3] )
|
65
66
|
message_block = [:row, :init, 'init_status', message_block[3]]
|
66
|
-
@
|
67
|
+
@init_message_block[4][:row_done] << message_block[3]
|
67
68
|
elsif @seeds.empty?
|
68
|
-
@
|
69
|
+
@waiting_rows << message_block[2]
|
69
70
|
message_block = [:row, :wait, nil, message_block[3]]
|
70
71
|
else
|
71
72
|
seed = @seeds.shift; @sprouts[seed[:id]] = seed
|
@@ -75,97 +76,95 @@ class Garden
|
|
75
76
|
end
|
76
77
|
|
77
78
|
def save_crop_for(message_block)
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
@
|
79
|
+
case message_block[1]
|
80
|
+
when :harvest
|
81
|
+
@sprouts[message_block[2][:id]] = nil
|
82
|
+
@crops[message_block[2][:id]] = message_block[2]
|
83
|
+
if @harvest_queue[message_block[2][:id]]
|
84
|
+
socket_send(message_block[0..2]+[@harvest_queue[message_block[2][:id]]])
|
85
|
+
@crops[message_block[2][:id]] = @harvest_queue[message_block[2][:id]] = nil
|
86
|
+
elsif @full_crop_message_block && @seeds.compact.empty? && @sprouts.compact.empty?
|
87
|
+
socket_send(message_block[0..1]+[@crops.compact,@full_crop_message_block[3]])
|
88
|
+
@crops.clear; @full_crop_message_block = nil
|
89
|
+
end
|
90
|
+
when :seed_all
|
91
|
+
@seed_all_message_block[4][:crops] << message_block[2]
|
92
|
+
if @seed_all_message_block[4][:crops].size == @seed_all_message_block[1]
|
93
|
+
@seed_all_message_block[2] = @seed_all_message_block[4][:crops]; @seed_all_message_block[4] = nil
|
94
|
+
socket_send(@seed_all_message_block.compact); @seed_all_message_block = nil
|
95
|
+
end
|
96
|
+
when :init
|
97
|
+
@init_message_block[4][:crops] << message_block[2]
|
98
|
+
if @init_message_block[4][:crops].size == @init_message_block[2]
|
99
|
+
@init_message_block[2] = @init_message_block[4][:crops]; @init_message_block[4] = nil
|
100
|
+
socket_send(@init_message_block.compact); @init_message_block = nil
|
101
|
+
end
|
86
102
|
end
|
87
103
|
end
|
88
104
|
|
89
105
|
def report_growth(message_block)
|
90
|
-
case message_block[
|
106
|
+
case message_block[1]
|
91
107
|
when :progress
|
92
108
|
value = @crops.size.to_f / (@crops.size + @sprouts.compact.size + @seeds.size)
|
93
109
|
value = 1 if value.nan?; progress = sprintf( "%.2f", value)
|
94
|
-
|
110
|
+
message_block[2] = progress
|
95
111
|
when :seed
|
96
|
-
|
112
|
+
message_block[2] = @seeds.size
|
97
113
|
when :sprout
|
98
|
-
|
114
|
+
message_block[2] = @sprouts.compact.size
|
99
115
|
when :crop
|
100
|
-
|
116
|
+
message_block[2] = @crops.size
|
101
117
|
else
|
102
|
-
|
118
|
+
message_block[2] = false
|
103
119
|
end
|
120
|
+
socket_send(message_block)
|
104
121
|
end
|
105
122
|
|
106
123
|
def harvest_some(message_block)
|
107
|
-
case message_block[
|
124
|
+
case message_block[1]
|
125
|
+
when :one
|
126
|
+
unless message_block[2].nil?
|
127
|
+
if @crops[message_block[2]]
|
128
|
+
socket_send(message_block[0..1]+[@crops[message_block[2]],message_block[3]])
|
129
|
+
@crops[message_block[2]] = nil
|
130
|
+
else
|
131
|
+
@harvest_queue[message_block[2]] = message_block[3]
|
132
|
+
end
|
133
|
+
else
|
134
|
+
message_block[2] = false; socket_send(message_block)
|
135
|
+
end
|
108
136
|
when :all
|
109
|
-
|
137
|
+
message_block[2] = {:seeds => @seeds, :sprouts => @sprouts.compact, :crops => @crops.compact}
|
138
|
+
socket_send(message_block)
|
110
139
|
when :seed
|
111
|
-
|
140
|
+
message_block[2] = @seeds; socket_send(message_block)
|
112
141
|
when :sprout
|
113
|
-
|
142
|
+
message_block[2] = @sprouts.compact; socket_send(message_block)
|
114
143
|
when :crop
|
115
|
-
|
116
|
-
@crops.clear
|
144
|
+
message_block[2] = @crops.compact; socket_send(message_block); @crops.clear
|
117
145
|
when :full_crop
|
118
146
|
if @seeds.compact.empty? && @sprouts.compact.empty?
|
119
|
-
|
120
|
-
@crops.clear
|
147
|
+
message_block[2] = @crops.compact; socket_send(message_block); @crops.clear
|
121
148
|
else
|
122
|
-
@
|
123
|
-
@mem_client_socket_path = message_block[3]
|
149
|
+
@full_crop_message_block = Array.new(message_block)
|
124
150
|
end
|
151
|
+
when :init
|
152
|
+
@init_message_block = Array.new(message_block)
|
153
|
+
@init_message_block[4] = {:row_done => [], :crops => []}
|
125
154
|
else
|
126
|
-
|
127
|
-
if @crops[message_block[2]]
|
128
|
-
socket_send([message_block[0],:garden,@crops[message_block[2]],message_block[3]])
|
129
|
-
@crops[message_block[2]] = nil
|
130
|
-
else
|
131
|
-
@harvest[message_block[2]] = {:client_socket_path => message_block[3]}
|
132
|
-
end
|
133
|
-
else
|
134
|
-
socket_send([message_block[0],:garden,false,message_block[3]])
|
135
|
-
end
|
155
|
+
message_block[2] = false; socket_send(message_block)
|
136
156
|
end
|
137
157
|
end
|
138
|
-
|
139
|
-
def ask_for_init_status(message_block)
|
140
|
-
@do_init = message_block[2]
|
141
|
-
@init_return = {:client_socket_path => message_block[3]}
|
142
|
-
end
|
143
|
-
|
144
|
-
def answer_init_status(message_block)
|
145
|
-
@init_all_crop << message_block[2]
|
146
|
-
if @init_all_crop.size == @do_init
|
147
|
-
socket_send([message_block[0],:garden,@init_all_crop, @init_return[:client_socket_path]])
|
148
|
-
@init_return = Hash.new; @init_done = Array.new; @do_init = nil; @init_all_crop = Array.new
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
def special_crop_seed_all(message_block)
|
153
|
-
@seed_all_crop << message_block[2]
|
154
|
-
if @seed_all_crop.size == @seed_all_message_block[1]
|
155
|
-
socket_send([message_block[0],:garden,@seed_all_crop, @seed_all_message_block[3]])
|
156
|
-
@seed_all_message_block = nil; @seed_all_done = Array.new; @seed_all_crop = Array.new
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
158
|
+
|
160
159
|
def close_all(message_block)
|
161
|
-
|
162
|
-
|
163
|
-
@
|
164
|
-
|
165
|
-
|
166
|
-
@
|
167
|
-
|
168
|
-
socket_send(
|
160
|
+
case message_block[1]
|
161
|
+
when :garden
|
162
|
+
@close_message_block = Array.new(message_block)
|
163
|
+
when :row
|
164
|
+
@close_message_block[2].delete(message_block[2].to_i)
|
165
|
+
if @close_message_block[2].empty?
|
166
|
+
@close_message_block[2] = {:seeds => @seeds, :sprouts => @sprouts.compact, :crops => @crops.compact}
|
167
|
+
socket_send(@close_message_block)
|
169
168
|
exit
|
170
169
|
end
|
171
170
|
end
|
data/lib/gardener.rb
CHANGED
@@ -48,7 +48,7 @@ class Gardener
|
|
48
48
|
# === Example
|
49
49
|
# puts gardener.init_status.inspect # => [{:message=>"init ok", :success=>true, :pid=>4760}, {:message=>"init failed", :success=>false, :pid=>4761}]
|
50
50
|
def init_status
|
51
|
-
message_block = socket_duplex([:init
|
51
|
+
message_block = socket_duplex([:harvest,:init,@garden_rows.pids.size,@garden_path])
|
52
52
|
message_block[2].map! do |row|
|
53
53
|
{:success => row[:success], :message => row[:message], :pid => row[:id]}
|
54
54
|
end
|
@@ -92,8 +92,8 @@ class Gardener
|
|
92
92
|
# progress = gardener.growth(:progress)
|
93
93
|
# puts "progress is now #{progress}" # => progress is now 0.75
|
94
94
|
|
95
|
-
def growth(
|
96
|
-
message_block = socket_duplex([:growth
|
95
|
+
def growth(option=:progress)
|
96
|
+
message_block = socket_duplex([:growth,option,nil,@garden_path])
|
97
97
|
return message_block[2]
|
98
98
|
end
|
99
99
|
|
@@ -101,18 +101,20 @@ class Gardener
|
|
101
101
|
# It has two different behaviour on queue data, one for ripe elements where it removes them from crop array ( on _seedID_ and :crop invocations ),
|
102
102
|
# for all other methods of invocation it leaves the queue intact.
|
103
103
|
# === Parameter
|
104
|
-
# The
|
105
|
-
# * seedID = return the result for a specific seed, if seed hasn't processed it wait until completed, _seedID_ is removed from crop array
|
104
|
+
# The option given as a symbol specifies the level of queue results you wish to get:
|
106
105
|
# * :crop = return an array of seed for which process has completed, empties the crop array.
|
107
106
|
# * :sprout = return an array of seed actually processing
|
108
107
|
# * :seed = return an array of seed waiting to be processed
|
109
108
|
# * :all = return a hash of respective arrays for crops, sprouts and seeds
|
110
109
|
# * :full_crop = wait for all seeds to be done processing, then returns as in :crop.
|
110
|
+
# * :one = return the result for a specific seed, if seed hasn't processed it wait until completed, _seed_id_ is removed from crop array
|
111
|
+
# When specifying :one as option, a seed ID is also required:
|
112
|
+
# * _seedID_ = the id as returned by the +seed+ method
|
111
113
|
# === Example
|
112
|
-
# seed1_result = gardener.harvest(id_seed_1)
|
114
|
+
# seed1_result = gardener.harvest(:one,id_seed_1)
|
113
115
|
|
114
|
-
def harvest(
|
115
|
-
message_block = socket_duplex([:harvest
|
116
|
+
def harvest(option,seed_id=nil)
|
117
|
+
message_block = socket_duplex([:harvest,option,seed_id,@garden_path])
|
116
118
|
return message_block[2]
|
117
119
|
end
|
118
120
|
|
@@ -122,7 +124,7 @@ class Gardener
|
|
122
124
|
# final_harvest = gardener.close
|
123
125
|
|
124
126
|
def close
|
125
|
-
message_block = socket_duplex([:close,:
|
127
|
+
message_block = socket_duplex([:close,:garden,@garden_rows.pids,@garden_path])
|
126
128
|
return message_block[2]
|
127
129
|
end
|
128
130
|
|
@@ -20,6 +20,8 @@ class Garden
|
|
20
20
|
# :title:Rows
|
21
21
|
|
22
22
|
class Rows
|
23
|
+
require 'rows_paths'
|
24
|
+
include Paths
|
23
25
|
require 'toolshed'
|
24
26
|
include Toolshed
|
25
27
|
attr_reader :pids
|
@@ -42,7 +44,6 @@ class Garden
|
|
42
44
|
@pids = []
|
43
45
|
rows.times do
|
44
46
|
@pids << fork do
|
45
|
-
@seed_all = false
|
46
47
|
set_my_socket_as_a(:row,garden_pid)
|
47
48
|
t1 = Thread.new do
|
48
49
|
gardener_block.call
|
@@ -54,42 +55,28 @@ class Garden
|
|
54
55
|
message_block = socket_duplex([:row,:row,my_socket_path,@garden_path])
|
55
56
|
case message_block[1]
|
56
57
|
when :sprout
|
57
|
-
|
58
|
+
sprout(message_block)
|
58
59
|
when :all
|
59
|
-
|
60
|
-
$seed = {:id => Process.pid, :seed => message_block[2]}
|
60
|
+
all(message_block)
|
61
61
|
when :wait
|
62
62
|
message_block = socket_recv
|
63
63
|
case message_block[1]
|
64
64
|
when :sprout
|
65
|
-
|
65
|
+
sprout(message_block)
|
66
66
|
when :all
|
67
|
-
|
68
|
-
$seed = {:id => Process.pid, :seed => message_block[2]}
|
67
|
+
all(message_block)
|
69
68
|
when :init
|
70
|
-
|
71
|
-
socket_send([:init_crop,:row,$init,@garden_path])
|
69
|
+
init
|
72
70
|
when :quit
|
73
|
-
|
74
|
-
socket_send([:close,:row,{:level => :seed, :pid => pid},@garden_path])
|
75
|
-
exit
|
71
|
+
quit
|
76
72
|
end
|
77
73
|
when :init
|
78
|
-
|
79
|
-
socket_send([:init_crop,:row,$init,@garden_path])
|
74
|
+
init
|
80
75
|
when :quit
|
81
|
-
|
82
|
-
socket_send([:close,:row,{:level => :seed, :pid => pid},@garden_path])
|
83
|
-
exit
|
76
|
+
quit
|
84
77
|
end
|
85
|
-
elsif
|
86
|
-
|
87
|
-
socket_send([:seed_all_crop,:row,$seed,@garden_path])
|
88
|
-
@seed_all = false
|
89
|
-
else
|
90
|
-
socket_send([:crop,:row,$seed,@garden_path])
|
91
|
-
end
|
92
|
-
$seed = nil;
|
78
|
+
elsif $seed[:success]
|
79
|
+
crop
|
93
80
|
else
|
94
81
|
t1.run
|
95
82
|
end
|
data/lib/rows_paths.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
class Garden
|
2
|
+
class Rows
|
3
|
+
# The Paths module is a set of method used by the Rows's forks.
|
4
|
+
# You will not need to use these methods unless you plan on refactoring the Rows.
|
5
|
+
#
|
6
|
+
# Author:: lp (mailto:lp@spiralix.org)
|
7
|
+
# Copyright:: 2008 Louis-Philippe Perron - Released under the terms of the MIT license
|
8
|
+
# :title:Rows
|
9
|
+
module Paths
|
10
|
+
|
11
|
+
def all(message_block)
|
12
|
+
$seed = {:id => Process.pid, :seed => message_block[2], :all => true}
|
13
|
+
end
|
14
|
+
|
15
|
+
def crop
|
16
|
+
if $seed[:all]
|
17
|
+
socket_send([:crop,:seed_all,$seed,@garden_path])
|
18
|
+
else
|
19
|
+
socket_send([:crop,:harvest,$seed,@garden_path])
|
20
|
+
end
|
21
|
+
$seed = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def init
|
25
|
+
$init = {:seed => 'init_status', :message => 'No Init Message', :id => Process.pid} if $init.nil?
|
26
|
+
socket_send([:crop,:init,$init,@garden_path])
|
27
|
+
end
|
28
|
+
|
29
|
+
def quit
|
30
|
+
socket_send([:close,:row,Process.pid,@garden_path])
|
31
|
+
exit
|
32
|
+
end
|
33
|
+
|
34
|
+
def sprout(message_block)
|
35
|
+
$seed = message_block[2]
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/test/tc_high_api.rb
CHANGED
@@ -69,7 +69,7 @@ class TestHighAPI < Test::Unit::TestCase
|
|
69
69
|
id = @g.seed(Process.pid)
|
70
70
|
assert_kind_of(Integer,id)
|
71
71
|
|
72
|
-
answer = @g.harvest(id)
|
72
|
+
answer = @g.harvest(:one,id)
|
73
73
|
assert_kind_of(Hash,answer)
|
74
74
|
assert_equal(Process.pid,answer[:seed])
|
75
75
|
assert_equal(id,answer[:id])
|
data/test/tc_multi_gardener.rb
CHANGED
@@ -40,8 +40,8 @@ class TestHighAPI < Test::Unit::TestCase
|
|
40
40
|
id1 = @g1.seed(Process.pid)
|
41
41
|
id2 = @g2.seed(Process.pid)
|
42
42
|
|
43
|
-
answer1 = @g1.harvest(id1)
|
44
|
-
answer2 = @g2.harvest(id2)
|
43
|
+
answer1 = @g1.harvest(:one,id1)
|
44
|
+
answer2 = @g2.harvest(:one,id2)
|
45
45
|
|
46
46
|
assert(answer1[:message] != answer2[:message])
|
47
47
|
assert(answer1[:message] =~ /gardener1.*/)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: abundance
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Louis-Philippe Perron
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-01-
|
12
|
+
date: 2009-01-18 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -25,8 +25,9 @@ files:
|
|
25
25
|
- lib/abundance.rb
|
26
26
|
- lib/garden.rb
|
27
27
|
- lib/garden_cycles.rb
|
28
|
-
- lib/garden_rows.rb
|
29
28
|
- lib/gardener.rb
|
29
|
+
- lib/rows.rb
|
30
|
+
- lib/rows_paths.rb
|
30
31
|
- lib/seed.rb
|
31
32
|
- lib/toolshed.rb
|
32
33
|
- test/tc_burst.rb
|