ruote-mon 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,8 @@
1
+
2
+ = ruote-mon - CHANGELOG.txt
3
+
4
+
5
+ == ruote-mon 2.3.0 released 2012/09/01
6
+
7
+ - initial release
8
+
@@ -0,0 +1,16 @@
1
+
2
+ = ruote-mon CREDITS.txt
3
+
4
+
5
+ == authors
6
+
7
+ - John Mettraux - http://jmettraux.wordpress.com
8
+
9
+
10
+ == contributors
11
+
12
+
13
+ == many thanks to
14
+
15
+ - Nathan Stults - https://github.com/PlasticLizard
16
+
@@ -0,0 +1,21 @@
1
+
2
+ Copyright (c) 2011-2012, John Mettraux, jmettraux@gmail.com
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+
@@ -0,0 +1,63 @@
1
+
2
+ = ruote-mon
3
+
4
+ A MongoDB storage for ruote.
5
+
6
+ This is the 'official' storage. There is also: https://github.com/PlasticLizard/ruote-mongodb but it contains optimizations for Plastic Lizard's team.
7
+
8
+ Works best with a 1.9.x Ruby.
9
+
10
+
11
+ == usage
12
+
13
+ require 'ruote'
14
+ require 'ruote-mon'
15
+
16
+ ruote = Ruote::Dashboard.new(
17
+ Ruote::Worker.new(
18
+ Ruote::Mon::Storage.new(
19
+ Mongo::Connection.new()['ruote_mon_test'],
20
+ {})))
21
+
22
+ # ...
23
+
24
+
25
+ == running tests
26
+
27
+ assuming you have
28
+
29
+ ruote/
30
+ ruote-mon/
31
+
32
+ start your MongoDB server and then
33
+
34
+
35
+ * unit tests :
36
+
37
+ get into ruote/ and do
38
+
39
+ ruby test/unit/storage.rb -- --mon
40
+
41
+ * functional tests :
42
+
43
+ get into ruote/ and do
44
+
45
+ ruby test/functional/test.rb -- --mon
46
+
47
+
48
+ == license
49
+
50
+ MIT
51
+
52
+
53
+ == links
54
+
55
+ * http://ruote.rubyforge.org/
56
+ * http://github.com/jmettraux/ruote-mon
57
+
58
+
59
+ == feedback
60
+
61
+ mailing list : http://groups.google.com/group/openwferu-users
62
+ irc : irc.freenode.net #ruote
63
+
@@ -0,0 +1,92 @@
1
+
2
+ $:.unshift('.') # 1.9.2
3
+
4
+ require 'rubygems'
5
+
6
+ require 'rake'
7
+ require 'rake/clean'
8
+ require 'rdoc/task'
9
+
10
+
11
+ #
12
+ # clean
13
+
14
+ CLEAN.include('pkg', 'rdoc')
15
+
16
+
17
+ #
18
+ # test / spec
19
+
20
+ task :test do
21
+
22
+ puts
23
+ puts "to test ruote-mon, head to your ruote/ dir and run"
24
+ puts
25
+ puts " ruby test/test.rb -- --mon"
26
+ puts
27
+ puts "but first, make sure your ruote-dm/test/functional_connection.rb"
28
+ puts "is set correctly."
29
+ puts
30
+ end
31
+
32
+ task :default => [ :test ]
33
+
34
+
35
+ #
36
+ # gem
37
+
38
+ GEMSPEC_FILE = Dir['*.gemspec'].first
39
+ GEMSPEC = eval(File.read(GEMSPEC_FILE))
40
+ GEMSPEC.validate
41
+
42
+
43
+ desc %{
44
+ builds the gem and places it in pkg/
45
+ }
46
+ task :build do
47
+
48
+ sh "gem build #{GEMSPEC_FILE}"
49
+ sh "mkdir pkg" rescue nil
50
+ sh "mv #{GEMSPEC.name}-#{GEMSPEC.version}.gem pkg/"
51
+ end
52
+
53
+ desc %{
54
+ builds the gem and pushes it to rubygems.org
55
+ }
56
+ task :push => :build do
57
+
58
+ sh "gem push pkg/#{GEMSPEC.name}-#{GEMSPEC.version}.gem"
59
+ end
60
+
61
+
62
+ #
63
+ # rdoc
64
+ #
65
+ # make sure to have rdoc 2.5.x to run that
66
+
67
+ Rake::RDocTask.new do |rd|
68
+
69
+ rd.main = 'README.rdoc'
70
+ rd.rdoc_dir = 'rdoc'
71
+
72
+ rd.rdoc_files.include(
73
+ 'README.rdoc', 'CHANGELOG.txt', 'CREDITS.txt', 'lib/**/*.rb')
74
+
75
+ rd.title = "#{GEMSPEC.name} #{GEMSPEC.version}"
76
+ end
77
+
78
+
79
+ #
80
+ # upload_rdoc
81
+
82
+ desc %{
83
+ upload the rdoc to rubyforge
84
+ }
85
+ task :upload_rdoc => [ :clean, :rdoc ] do
86
+
87
+ account = 'jmettraux@rubyforge.org'
88
+ webdir = '/var/www/gforge-projects/ruote'
89
+
90
+ sh "rsync -azv -e ssh rdoc/#{GEMSPEC.name}_rdoc #{account}:#{webdir}/"
91
+ end
92
+
@@ -0,0 +1,9 @@
1
+
2
+ [ ] Storage#drop_indexes
3
+
4
+ == for the StorageParticipant
5
+ [ ] Storage#by_wfid
6
+ [ ] Storage#by_field
7
+ [ ] Storage#by_participant
8
+ [ ] Storage#query_workitems
9
+
@@ -0,0 +1,3 @@
1
+
2
+ require 'ruote/mon/storage'
3
+
@@ -0,0 +1,3 @@
1
+
2
+ require 'ruote/mon/storage'
3
+
@@ -0,0 +1,333 @@
1
+ # encoding: UTF-8
2
+
3
+ #--
4
+ # Copyright (c) 2011-2012, John Mettraux, jmettraux@gmail.com
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files(the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ # THE SOFTWARE.
23
+ #
24
+ # Made in Japan.
25
+ #++
26
+
27
+ require 'mongo'
28
+
29
+ require 'ruote/storage/base'
30
+ require 'ruote/mon/version'
31
+
32
+
33
+ module Ruote
34
+ module Mon
35
+
36
+ class Storage
37
+
38
+ include Ruote::StorageBase
39
+
40
+ TYPES = %w[
41
+ msgs schedules expressions workitems errors
42
+ configurations variables trackers history
43
+ ]
44
+
45
+ attr_reader :db
46
+
47
+ def initialize(mongo_db, options={})
48
+
49
+ @db = mongo_db
50
+ @options = options
51
+
52
+ #collection('msgs').drop_index('_id_')
53
+ # can't do that...
54
+
55
+ (TYPES - %w[ msgs schedules ]).each do |t|
56
+ collection(t).ensure_index('_wfid')
57
+ collection(t).ensure_index([ [ '_id', 1 ], [ '_rev', 1 ] ])
58
+ end
59
+ collection('schedules').ensure_index('_wfid')
60
+ collection('schedules').ensure_index('at')
61
+
62
+ replace_engine_configuration(options)
63
+ end
64
+
65
+ def get_schedules(delta, now)
66
+
67
+ from_mongo(collection('schedules').find(
68
+ 'at' => { '$lte' => Ruote.time_to_utc_s(now) }
69
+ ).to_a)
70
+ end
71
+
72
+ # Returns true if the doc was successfully deleted.
73
+ #
74
+ def reserve(doc)
75
+
76
+ r = collection(doc).remove(
77
+ { '_id' => doc['_id'] },
78
+ :safe => true)
79
+
80
+ r['n'] == 1
81
+ end
82
+
83
+ # Puts a msg. Doesn't use :safe => true, it's always an insert with a
84
+ # new id.
85
+ #
86
+ def put_msg(action, options)
87
+
88
+ msg = prepare_msg_doc(action, options)
89
+ msg['put_at'] = Ruote.now_to_utc_s
90
+
91
+ msg['_rev'] = 0
92
+ # in case of msg replay
93
+
94
+ collection(msg).insert(to_mongo(msg))
95
+ end
96
+
97
+ def put(doc, opts={})
98
+
99
+ original = doc
100
+ doc = doc.dup
101
+
102
+ doc['_rev'] = (doc['_rev'] || -1) + 1
103
+ doc['_wfid'] = doc['_id'].split('!').last
104
+ doc['put_at'] = Ruote.now_to_utc_s
105
+
106
+ if doc['type'] == 'schedules'
107
+ doc['_wfid'] = doc['_wfid'].split('-')[0..-2].join('-')
108
+ end
109
+
110
+ r = begin
111
+ collection(doc).update(
112
+ { '_id' => doc['_id'], '_rev' => original['_rev'] },
113
+ to_mongo(opts[:update_rev] ? Ruote.fulldup(doc) : doc),
114
+ :safe => true, :upsert => original['_rev'].nil?)
115
+ rescue Mongo::OperationFailure
116
+ false
117
+ end
118
+
119
+ if r && (r['updatedExisting'] || original['_rev'].nil?)
120
+ original.merge!(
121
+ '_rev' => doc['_rev'], 'put_at' => doc['put_at']
122
+ ) if opts[:update_rev]
123
+ nil
124
+ else
125
+ from_mongo(collection(doc).find_one('_id' => doc['_id']) || true)
126
+ end
127
+ end
128
+
129
+ def get(type, key)
130
+
131
+ from_mongo(collection(type).find_one('_id' => key))
132
+ end
133
+
134
+ def delete(doc)
135
+
136
+ rev = doc['_rev']
137
+
138
+ raise ArgumentError.new("can't delete doc without _rev") unless rev
139
+
140
+ r = collection(doc).remove(
141
+ { '_id' => doc['_id'], '_rev' => doc['_rev'] },
142
+ :safe => true)
143
+
144
+ if r['n'] == 1
145
+ nil
146
+ else
147
+ from_mongo(collection(doc).find_one('_id' => doc['_id']) || true)
148
+ end
149
+ end
150
+
151
+ def get_many(type, key=nil, opts={})
152
+
153
+ opts = Ruote.keys_to_s(opts)
154
+ keys = key ? Array(key) : nil
155
+
156
+ cursor = if keys.nil?
157
+ collection(type).find
158
+ elsif keys.first.is_a?(Regexp)
159
+ collection(type).find('_id' => { '$in' => keys })
160
+ else # a String
161
+ collection(type).find('_wfid' => { '$in' => keys })
162
+ end
163
+
164
+ paginate(cursor, opts)
165
+ end
166
+
167
+ def ids(type)
168
+
169
+ collection(type).find(
170
+ {},
171
+ :fields => [], :sort => [ '_id', Mongo::ASCENDING ]
172
+ ).collect { |d|
173
+ d['_id']
174
+ }
175
+ end
176
+
177
+ def purge!
178
+
179
+ TYPES.each { |t| collection(t).remove }
180
+ end
181
+
182
+ # Shuts this storage down.
183
+ #
184
+ def close
185
+
186
+ @db.connection.close
187
+ end
188
+
189
+ # Shuts this storage down.
190
+ #
191
+ def shutdown
192
+
193
+ @db.connection.close
194
+ end
195
+
196
+ # Mainly used by ruote's test/unit/ut_17_storage.rb
197
+ #
198
+ def add_type(type)
199
+
200
+ # nothing to be done
201
+ end
202
+
203
+ # Nukes a db type and reputs it(losing all the documents that were in it).
204
+ #
205
+ def purge_type!(type)
206
+
207
+ collection(type).remove
208
+ end
209
+
210
+ #--
211
+ # workitem methods
212
+ #++
213
+
214
+ # Note: no check on value, MongoDB specific queries can be used...
215
+ #
216
+ # http://www.mongodb.org/display/DOCS/Advanced+Queries
217
+ #
218
+ def by_field(type, key, value, opts={})
219
+
220
+ value = { '$exists' => true } if value.nil?
221
+
222
+ paginate_workitems(
223
+ collection(type).find("fields.#{key}" => value),
224
+ opts)
225
+ end
226
+
227
+ def by_participant(type, participant_name, opts={})
228
+
229
+ paginate_workitems(
230
+ collection(type).find('participant_name' => participant_name),
231
+ opts)
232
+ end
233
+
234
+ def query_workitems(query)
235
+
236
+ query = Ruote.keys_to_s(query)
237
+
238
+ opts = {}
239
+ opts['count'] = query.delete('count')
240
+ opts['skip'] = query.delete('skip') || query.delete('offset')
241
+ opts['limit'] = query.delete('limit')
242
+ opts['descending'] = query.delete('descending')
243
+
244
+ wfid = query.delete('wfid')
245
+ pname = query.delete('participant') || query.delete('participant_name')
246
+
247
+ query = query.each_with_object({}) { |(k, v), h| h["fields.#{k}"] = v }
248
+
249
+ query['wfid'] = wfid if wfid
250
+ query['participant_name'] = pname if pname
251
+
252
+ paginate_workitems(
253
+ collection('workitems').find(query),
254
+ opts)
255
+ end
256
+
257
+ protected
258
+
259
+ # Given a doc, returns the MongoDB collection it should go to.
260
+ #
261
+ def collection(doc_or_type)
262
+
263
+ @db.collection(
264
+ doc_or_type.is_a?(String) ? doc_or_type : doc_or_type['type'])
265
+ end
266
+
267
+ # Given a cursor, applies the count/skip/limit/descending options
268
+ # if requested.
269
+ #
270
+ def paginate(cursor, opts)
271
+
272
+ opts = Ruote.keys_to_s(opts)
273
+
274
+ return cursor.count if opts['count']
275
+
276
+ cursor.sort(
277
+ '_id', opts['descending'] ? Mongo::DESCENDING : Mongo::ASCENDING)
278
+
279
+ cursor.skip(opts['skip'])
280
+ cursor.limit(opts['limit'])
281
+
282
+ from_mongo(cursor.to_a)
283
+ end
284
+
285
+ # Wrapping around #paginate for workitems.
286
+ #
287
+ def paginate_workitems(cursor, opts)
288
+
289
+ docs = paginate(cursor, opts)
290
+
291
+ docs.is_a?(Array) ? docs.collect { |h| Ruote::Workitem.new(h) } : docs
292
+ end
293
+
294
+ # Prepares the doc for insertion in MongoDB (takes care of keys beginning
295
+ # with '$' and/or containing '.')
296
+ #
297
+ def to_mongo(doc)
298
+
299
+ # vertical tilde and ogonek to the rescue
300
+
301
+ Ruote.deep_mutate(doc, [ /^\$/, /\./ ]) { |h, k, v|
302
+ h.delete(k)
303
+ h[k.gsub(/^\$/, 'ⸯ$').gsub(/\./, '˛')] = v
304
+ }
305
+ end
306
+
307
+ # The real work being #from_mongo is done here.
308
+ #
309
+ def _from_mongo(doc)
310
+
311
+ # vertical tilde and ogonek to the rescue
312
+
313
+ Ruote.deep_mutate(doc, [ /^ⸯ\$/, /˛/ ]) { |h, k, v|
314
+ h.delete(k)
315
+ h[k.gsub(/^ⸯ\$/, '$').gsub(/˛/, '.')] = v
316
+ }
317
+ end
318
+
319
+ # Prepare the doc for consumption out of MongoDB (takes care of keys
320
+ # beginning with '$' and/or containing '.')
321
+ #
322
+ def from_mongo(docs)
323
+
324
+ case docs
325
+ when true, nil then docs
326
+ when Array then docs.collect { |doc| _from_mongo(doc) }
327
+ else _from_mongo(docs)
328
+ end
329
+ end
330
+ end
331
+ end
332
+ end
333
+
@@ -0,0 +1,32 @@
1
+ #--
2
+ # Copyright (c) 2011-2012, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files(the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ module Ruote
27
+ module Mon
28
+
29
+ VERSION = '2.3.0'
30
+ end
31
+ end
32
+
@@ -0,0 +1,35 @@
1
+
2
+ Gem::Specification.new do |s|
3
+
4
+ s.name = 'ruote-mon'
5
+
6
+ s.version = File.read(
7
+ File.expand_path('../lib/ruote/mon/version.rb', __FILE__)
8
+ ).match(/ VERSION *= *['"]([^'"]+)/)[1]
9
+
10
+ s.platform = Gem::Platform::RUBY
11
+ s.authors = [ 'John Mettraux' ]
12
+ s.email = [ 'jmettraux@gmail.com' ]
13
+ s.homepage = 'http://ruote.rubyforge.org'
14
+ s.rubyforge_project = 'ruote'
15
+ s.summary = 'MongoDB storage for ruote (a Ruby workflow engine)'
16
+ s.description = %q{
17
+ MongoDB storage for ruote (a Ruby workflow engine)
18
+ }
19
+
20
+ #s.files = `git ls-files`.split("\n")
21
+ s.files = Dir[
22
+ 'Rakefile',
23
+ 'lib/**/*.rb', 'spec/**/*.rb', 'test/**/*.rb',
24
+ '*.gemspec', '*.txt', '*.rdoc', '*.md'
25
+ ]
26
+
27
+ s.add_runtime_dependency 'bson_ext'#, '>= 1.4.0'
28
+ s.add_runtime_dependency 'mongo'#, '>= 1.4.0'
29
+ s.add_runtime_dependency 'ruote', ">= #{s.version}"
30
+
31
+ s.add_development_dependency 'rake'
32
+
33
+ s.require_path = 'lib'
34
+ end
35
+
@@ -0,0 +1,28 @@
1
+
2
+ #
3
+ # testing ruote-mon
4
+ #
5
+ # Tue Nov 22 16:54:57 JST 2011
6
+ #
7
+
8
+ require 'ruote-mon'
9
+
10
+
11
+ def new_storage(opts)
12
+
13
+ #con = Mongo::Connection.new
14
+ #
15
+ # not thread-safe
16
+
17
+ #con = Mongo::Connection.new(nil, nil, :refresh_mode => :sync)
18
+ #
19
+ # http://groups.google.com/group/mongodb-user/browse_thread/thread/7d09df9fa765891e
20
+ #
21
+ # but it doesn't work.
22
+
23
+ con = Mongo::Connection.new(
24
+ '127.0.0.1', 27017, :pool_size => 14, :pool_timeout => 3)
25
+
26
+ Ruote::Mon::Storage.new(con['ruote_mon_test'], opts)
27
+ end
28
+
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruote-mon
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.3.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - John Mettraux
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-01 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bson_ext
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: mongo
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: ruote
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 2.3.0
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 2.3.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: ! '
79
+
80
+ MongoDB storage for ruote (a Ruby workflow engine)
81
+
82
+ '
83
+ email:
84
+ - jmettraux@gmail.com
85
+ executables: []
86
+ extensions: []
87
+ extra_rdoc_files: []
88
+ files:
89
+ - Rakefile
90
+ - lib/ruote/mon/storage.rb
91
+ - lib/ruote/mon/version.rb
92
+ - lib/ruote/mon.rb
93
+ - lib/ruote-mon.rb
94
+ - test/connection.rb
95
+ - ruote-mon.gemspec
96
+ - CHANGELOG.txt
97
+ - CREDITS.txt
98
+ - LICENSE.txt
99
+ - TODO.txt
100
+ - README.rdoc
101
+ homepage: http://ruote.rubyforge.org
102
+ licenses: []
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ! '>='
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project: ruote
121
+ rubygems_version: 1.8.24
122
+ signing_key:
123
+ specification_version: 3
124
+ summary: MongoDB storage for ruote (a Ruby workflow engine)
125
+ test_files: []