rubysl-pstore 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +8 -0
- data/Gemfile +4 -0
- data/LICENSE +25 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/lib/pstore.rb +1 -0
- data/lib/rubysl/pstore.rb +2 -0
- data/lib/rubysl/pstore/pstore.rb +395 -0
- data/lib/rubysl/pstore/version.rb +5 -0
- data/rubysl-pstore.gemspec +23 -0
- metadata +111 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 49e8c464bdca0f27119a2c5e04523932784880e7
|
4
|
+
data.tar.gz: 4e10e4cf5ec7e64f77589b6918b4bb66aadba2d8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c0194a5e9c670355a299c6cf3c78c74711ede3aef8f2446c2231a3216371256bb3287be3458766ce9e396124cc91841666ecd2fcaaefc4b7e90ac5339efedd52
|
7
|
+
data.tar.gz: d71099fd0bd5172c5ad39ab78f771d4904f6270b8447ead45958e533d1648fcc19c4cf3b284a45f0ade1d1f944db3c2c264dfc7e960dae8acab084523c5c6261
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
Copyright (c) 2013, Brian Shirai
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
8
|
+
list of conditions and the following disclaimer.
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
10
|
+
this list of conditions and the following disclaimer in the documentation
|
11
|
+
and/or other materials provided with the distribution.
|
12
|
+
3. Neither the name of the library nor the names of its contributors may be
|
13
|
+
used to endorse or promote products derived from this software without
|
14
|
+
specific prior written permission.
|
15
|
+
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
17
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
18
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
19
|
+
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT,
|
20
|
+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
21
|
+
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
22
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
23
|
+
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
24
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
25
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Rubysl::Pstore
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'rubysl-pstore'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install rubysl-pstore
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/pstore.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "rubysl/pstore"
|
@@ -0,0 +1,395 @@
|
|
1
|
+
# = PStore -- Transactional File Storage for Ruby Objects
|
2
|
+
#
|
3
|
+
# pstore.rb -
|
4
|
+
# originally by matz
|
5
|
+
# documentation by Kev Jackson and James Edward Gray II
|
6
|
+
#
|
7
|
+
# See PStore for documentation.
|
8
|
+
|
9
|
+
|
10
|
+
require "fileutils"
|
11
|
+
require "digest/md5"
|
12
|
+
|
13
|
+
#
|
14
|
+
# PStore implements a file based persistence mechanism based on a Hash. User
|
15
|
+
# code can store hierarchies of Ruby objects (values) into the data store file
|
16
|
+
# by name (keys). An object hierarchy may be just a single object. User code
|
17
|
+
# may later read values back from the data store or even update data, as needed.
|
18
|
+
#
|
19
|
+
# The transactional behavior ensures that any changes succeed or fail together.
|
20
|
+
# This can be used to ensure that the data store is not left in a transitory
|
21
|
+
# state, where some values were updated but others were not.
|
22
|
+
#
|
23
|
+
# Behind the scenes, Ruby objects are stored to the data store file with
|
24
|
+
# Marshal. That carries the usual limitations. Proc objects cannot be
|
25
|
+
# marshalled, for example.
|
26
|
+
#
|
27
|
+
# == Usage example:
|
28
|
+
#
|
29
|
+
# require "pstore"
|
30
|
+
#
|
31
|
+
# # a mock wiki object...
|
32
|
+
# class WikiPage
|
33
|
+
# def initialize( page_name, author, contents )
|
34
|
+
# @page_name = page_name
|
35
|
+
# @revisions = Array.new
|
36
|
+
#
|
37
|
+
# add_revision(author, contents)
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# attr_reader :page_name
|
41
|
+
#
|
42
|
+
# def add_revision( author, contents )
|
43
|
+
# @revisions << { :created => Time.now,
|
44
|
+
# :author => author,
|
45
|
+
# :contents => contents }
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# def wiki_page_references
|
49
|
+
# [@page_name] + @revisions.last[:contents].scan(/\b(?:[A-Z]+[a-z]+){2,}/)
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# # ...
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# # create a new page...
|
56
|
+
# home_page = WikiPage.new( "HomePage", "James Edward Gray II",
|
57
|
+
# "A page about the JoysOfDocumentation..." )
|
58
|
+
#
|
59
|
+
# # then we want to update page data and the index together, or not at all...
|
60
|
+
# wiki = PStore.new("wiki_pages.pstore")
|
61
|
+
# wiki.transaction do # begin transaction; do all of this or none of it
|
62
|
+
# # store page...
|
63
|
+
# wiki[home_page.page_name] = home_page
|
64
|
+
# # ensure that an index has been created...
|
65
|
+
# wiki[:wiki_index] ||= Array.new
|
66
|
+
# # update wiki index...
|
67
|
+
# wiki[:wiki_index].push(*home_page.wiki_page_references)
|
68
|
+
# end # commit changes to wiki data store file
|
69
|
+
#
|
70
|
+
# ### Some time later... ###
|
71
|
+
#
|
72
|
+
# # read wiki data...
|
73
|
+
# wiki.transaction(true) do # begin read-only transaction, no changes allowed
|
74
|
+
# wiki.roots.each do |data_root_name|
|
75
|
+
# p data_root_name
|
76
|
+
# p wiki[data_root_name]
|
77
|
+
# end
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
class PStore
|
81
|
+
binmode = defined?(File::BINARY) ? File::BINARY : 0
|
82
|
+
RDWR_ACCESS = File::RDWR | File::CREAT | binmode
|
83
|
+
RD_ACCESS = File::RDONLY | binmode
|
84
|
+
WR_ACCESS = File::WRONLY | File::CREAT | File::TRUNC | binmode
|
85
|
+
|
86
|
+
# The error type thrown by all PStore methods.
|
87
|
+
class Error < StandardError
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# To construct a PStore object, pass in the _file_ path where you would like
|
92
|
+
# the data to be stored.
|
93
|
+
#
|
94
|
+
def initialize(file)
|
95
|
+
dir = File::dirname(file)
|
96
|
+
unless File::directory? dir
|
97
|
+
raise PStore::Error, format("directory %s does not exist", dir)
|
98
|
+
end
|
99
|
+
if File::exist? file and not File::readable? file
|
100
|
+
raise PStore::Error, format("file %s not readable", file)
|
101
|
+
end
|
102
|
+
@transaction = false
|
103
|
+
@filename = file
|
104
|
+
@abort = false
|
105
|
+
end
|
106
|
+
|
107
|
+
# Raises PStore::Error if the calling code is not in a PStore#transaction.
|
108
|
+
def in_transaction
|
109
|
+
raise PStore::Error, "not in transaction" unless @transaction
|
110
|
+
end
|
111
|
+
#
|
112
|
+
# Raises PStore::Error if the calling code is not in a PStore#transaction or
|
113
|
+
# if the code is in a read-only PStore#transaction.
|
114
|
+
#
|
115
|
+
def in_transaction_wr()
|
116
|
+
in_transaction()
|
117
|
+
raise PStore::Error, "in read-only transaction" if @rdonly
|
118
|
+
end
|
119
|
+
private :in_transaction, :in_transaction_wr
|
120
|
+
|
121
|
+
#
|
122
|
+
# Retrieves a value from the PStore file data, by _name_. The hierarchy of
|
123
|
+
# Ruby objects stored under that root _name_ will be returned.
|
124
|
+
#
|
125
|
+
# *WARNING*: This method is only valid in a PStore#transaction. It will
|
126
|
+
# raise PStore::Error if called at any other time.
|
127
|
+
#
|
128
|
+
def [](name)
|
129
|
+
in_transaction
|
130
|
+
@table[name]
|
131
|
+
end
|
132
|
+
#
|
133
|
+
# This method is just like PStore#[], save that you may also provide a
|
134
|
+
# _default_ value for the object. In the event the specified _name_ is not
|
135
|
+
# found in the data store, your _default_ will be returned instead. If you do
|
136
|
+
# not specify a default, PStore::Error will be raised if the object is not
|
137
|
+
# found.
|
138
|
+
#
|
139
|
+
# *WARNING*: This method is only valid in a PStore#transaction. It will
|
140
|
+
# raise PStore::Error if called at any other time.
|
141
|
+
#
|
142
|
+
def fetch(name, default=PStore::Error)
|
143
|
+
in_transaction
|
144
|
+
unless @table.key? name
|
145
|
+
if default==PStore::Error
|
146
|
+
raise PStore::Error, format("undefined root name `%s'", name)
|
147
|
+
else
|
148
|
+
return default
|
149
|
+
end
|
150
|
+
end
|
151
|
+
@table[name]
|
152
|
+
end
|
153
|
+
#
|
154
|
+
# Stores an individual Ruby object or a hierarchy of Ruby objects in the data
|
155
|
+
# store file under the root _name_. Assigning to a _name_ already in the data
|
156
|
+
# store clobbers the old data.
|
157
|
+
#
|
158
|
+
# == Example:
|
159
|
+
#
|
160
|
+
# require "pstore"
|
161
|
+
#
|
162
|
+
# store = PStore.new("data_file.pstore")
|
163
|
+
# store.transaction do # begin transaction
|
164
|
+
# # load some data into the store...
|
165
|
+
# store[:single_object] = "My data..."
|
166
|
+
# store[:obj_heirarchy] = { "Kev Jackson" => ["rational.rb", "pstore.rb"],
|
167
|
+
# "James Gray" => ["erb.rb", "pstore.rb"] }
|
168
|
+
# end # commit changes to data store file
|
169
|
+
#
|
170
|
+
# *WARNING*: This method is only valid in a PStore#transaction and it cannot
|
171
|
+
# be read-only. It will raise PStore::Error if called at any other time.
|
172
|
+
#
|
173
|
+
def []=(name, value)
|
174
|
+
in_transaction_wr()
|
175
|
+
@table[name] = value
|
176
|
+
end
|
177
|
+
#
|
178
|
+
# Removes an object hierarchy from the data store, by _name_.
|
179
|
+
#
|
180
|
+
# *WARNING*: This method is only valid in a PStore#transaction and it cannot
|
181
|
+
# be read-only. It will raise PStore::Error if called at any other time.
|
182
|
+
#
|
183
|
+
def delete(name)
|
184
|
+
in_transaction_wr()
|
185
|
+
@table.delete name
|
186
|
+
end
|
187
|
+
|
188
|
+
#
|
189
|
+
# Returns the names of all object hierarchies currently in the store.
|
190
|
+
#
|
191
|
+
# *WARNING*: This method is only valid in a PStore#transaction. It will
|
192
|
+
# raise PStore::Error if called at any other time.
|
193
|
+
#
|
194
|
+
def roots
|
195
|
+
in_transaction
|
196
|
+
@table.keys
|
197
|
+
end
|
198
|
+
#
|
199
|
+
# Returns true if the supplied _name_ is currently in the data store.
|
200
|
+
#
|
201
|
+
# *WARNING*: This method is only valid in a PStore#transaction. It will
|
202
|
+
# raise PStore::Error if called at any other time.
|
203
|
+
#
|
204
|
+
def root?(name)
|
205
|
+
in_transaction
|
206
|
+
@table.key? name
|
207
|
+
end
|
208
|
+
# Returns the path to the data store file.
|
209
|
+
def path
|
210
|
+
@filename
|
211
|
+
end
|
212
|
+
|
213
|
+
#
|
214
|
+
# Ends the current PStore#transaction, committing any changes to the data
|
215
|
+
# store immediately.
|
216
|
+
#
|
217
|
+
# == Example:
|
218
|
+
#
|
219
|
+
# require "pstore"
|
220
|
+
#
|
221
|
+
# store = PStore.new("data_file.pstore")
|
222
|
+
# store.transaction do # begin transaction
|
223
|
+
# # load some data into the store...
|
224
|
+
# store[:one] = 1
|
225
|
+
# store[:two] = 2
|
226
|
+
#
|
227
|
+
# store.commit # end transaction here, committing changes
|
228
|
+
#
|
229
|
+
# store[:three] = 3 # this change is never reached
|
230
|
+
# end
|
231
|
+
#
|
232
|
+
# *WARNING*: This method is only valid in a PStore#transaction. It will
|
233
|
+
# raise PStore::Error if called at any other time.
|
234
|
+
#
|
235
|
+
def commit
|
236
|
+
in_transaction
|
237
|
+
@abort = false
|
238
|
+
throw :pstore_abort_transaction
|
239
|
+
end
|
240
|
+
#
|
241
|
+
# Ends the current PStore#transaction, discarding any changes to the data
|
242
|
+
# store.
|
243
|
+
#
|
244
|
+
# == Example:
|
245
|
+
#
|
246
|
+
# require "pstore"
|
247
|
+
#
|
248
|
+
# store = PStore.new("data_file.pstore")
|
249
|
+
# store.transaction do # begin transaction
|
250
|
+
# store[:one] = 1 # this change is not applied, see below...
|
251
|
+
# store[:two] = 2 # this change is not applied, see below...
|
252
|
+
#
|
253
|
+
# store.abort # end transaction here, discard all changes
|
254
|
+
#
|
255
|
+
# store[:three] = 3 # this change is never reached
|
256
|
+
# end
|
257
|
+
#
|
258
|
+
# *WARNING*: This method is only valid in a PStore#transaction. It will
|
259
|
+
# raise PStore::Error if called at any other time.
|
260
|
+
#
|
261
|
+
def abort
|
262
|
+
in_transaction
|
263
|
+
@abort = true
|
264
|
+
throw :pstore_abort_transaction
|
265
|
+
end
|
266
|
+
|
267
|
+
#
|
268
|
+
# Opens a new transaction for the data store. Code executed inside a block
|
269
|
+
# passed to this method may read and write data to and from the data store
|
270
|
+
# file.
|
271
|
+
#
|
272
|
+
# At the end of the block, changes are committed to the data store
|
273
|
+
# automatically. You may exit the transaction early with a call to either
|
274
|
+
# PStore#commit or PStore#abort. See those methods for details about how
|
275
|
+
# changes are handled. Raising an uncaught Exception in the block is
|
276
|
+
# equivalent to calling PStore#abort.
|
277
|
+
#
|
278
|
+
# If _read_only_ is set to +true+, you will only be allowed to read from the
|
279
|
+
# data store during the transaction and any attempts to change the data will
|
280
|
+
# raise a PStore::Error.
|
281
|
+
#
|
282
|
+
# Note that PStore does not support nested transactions.
|
283
|
+
#
|
284
|
+
def transaction(read_only=false) # :yields: pstore
|
285
|
+
raise PStore::Error, "nested transaction" if @transaction
|
286
|
+
begin
|
287
|
+
@rdonly = read_only
|
288
|
+
@abort = false
|
289
|
+
@transaction = true
|
290
|
+
value = nil
|
291
|
+
new_file = @filename + ".new"
|
292
|
+
|
293
|
+
content = nil
|
294
|
+
unless read_only
|
295
|
+
file = File.open(@filename, RDWR_ACCESS)
|
296
|
+
file.flock(File::LOCK_EX)
|
297
|
+
commit_new(file) if FileTest.exist?(new_file)
|
298
|
+
content = file.read()
|
299
|
+
else
|
300
|
+
begin
|
301
|
+
file = File.open(@filename, RD_ACCESS)
|
302
|
+
file.flock(File::LOCK_SH)
|
303
|
+
content = (File.open(new_file, RD_ACCESS) {|n| n.read} rescue file.read())
|
304
|
+
rescue Errno::ENOENT
|
305
|
+
content = ""
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
if content != ""
|
310
|
+
@table = load(content)
|
311
|
+
if !read_only
|
312
|
+
size = content.size
|
313
|
+
md5 = Digest::MD5.digest(content)
|
314
|
+
end
|
315
|
+
else
|
316
|
+
@table = {}
|
317
|
+
end
|
318
|
+
content = nil # unreference huge data
|
319
|
+
|
320
|
+
begin
|
321
|
+
catch(:pstore_abort_transaction) do
|
322
|
+
value = yield(self)
|
323
|
+
end
|
324
|
+
rescue Exception
|
325
|
+
@abort = true
|
326
|
+
raise
|
327
|
+
ensure
|
328
|
+
if !read_only and !@abort
|
329
|
+
tmp_file = @filename + ".tmp"
|
330
|
+
content = dump(@table)
|
331
|
+
if !md5 || size != content.size || md5 != Digest::MD5.digest(content)
|
332
|
+
File.open(tmp_file, WR_ACCESS) {|t| t.write(content)}
|
333
|
+
File.rename(tmp_file, new_file)
|
334
|
+
commit_new(file)
|
335
|
+
end
|
336
|
+
content = nil # unreference huge data
|
337
|
+
end
|
338
|
+
end
|
339
|
+
ensure
|
340
|
+
@table = nil
|
341
|
+
@transaction = false
|
342
|
+
file.close if file
|
343
|
+
end
|
344
|
+
value
|
345
|
+
end
|
346
|
+
|
347
|
+
# This method is just a wrapped around Marshal.dump.
|
348
|
+
def dump(table) # :nodoc:
|
349
|
+
Marshal::dump(table)
|
350
|
+
end
|
351
|
+
|
352
|
+
# This method is just a wrapped around Marshal.load.
|
353
|
+
def load(content) # :nodoc:
|
354
|
+
Marshal::load(content)
|
355
|
+
end
|
356
|
+
|
357
|
+
# This method is just a wrapped around Marshal.load.
|
358
|
+
def load_file(file) # :nodoc:
|
359
|
+
Marshal::load(file)
|
360
|
+
end
|
361
|
+
|
362
|
+
private
|
363
|
+
# Commits changes to the data store file.
|
364
|
+
def commit_new(f)
|
365
|
+
f.truncate(0)
|
366
|
+
f.rewind
|
367
|
+
new_file = @filename + ".new"
|
368
|
+
File.open(new_file, RD_ACCESS) do |nf|
|
369
|
+
FileUtils.copy_stream(nf, f)
|
370
|
+
end
|
371
|
+
File.unlink(new_file)
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
# :enddoc:
|
376
|
+
|
377
|
+
if __FILE__ == $0
|
378
|
+
db = PStore.new("/tmp/foo")
|
379
|
+
db.transaction do
|
380
|
+
p db.roots
|
381
|
+
ary = db["root"] = [1,2,3,4]
|
382
|
+
ary[1] = [1,1.5]
|
383
|
+
end
|
384
|
+
|
385
|
+
1000.times do
|
386
|
+
db.transaction do
|
387
|
+
db["root"][0] += 1
|
388
|
+
p db["root"][0]
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
db.transaction(true) do
|
393
|
+
p db["root"]
|
394
|
+
end
|
395
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require './lib/rubysl/pstore/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = "rubysl-pstore"
|
6
|
+
spec.version = RubySL::PStore::VERSION
|
7
|
+
spec.authors = ["Brian Shirai"]
|
8
|
+
spec.email = ["brixen@gmail.com"]
|
9
|
+
spec.description = %q{Ruby standard library pstore.}
|
10
|
+
spec.summary = %q{Ruby standard library pstore.}
|
11
|
+
spec.homepage = "https://github.com/rubysl/rubysl-pstore"
|
12
|
+
spec.license = "BSD"
|
13
|
+
|
14
|
+
spec.files = `git ls-files`.split($/)
|
15
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
20
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
21
|
+
spec.add_development_dependency "mspec", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rubysl-prettyprint", "~> 1.0"
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubysl-pstore
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brian Shirai
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.5'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubysl-prettyprint
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.0'
|
69
|
+
description: Ruby standard library pstore.
|
70
|
+
email:
|
71
|
+
- brixen@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- .travis.yml
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- lib/pstore.rb
|
83
|
+
- lib/rubysl/pstore.rb
|
84
|
+
- lib/rubysl/pstore/pstore.rb
|
85
|
+
- lib/rubysl/pstore/version.rb
|
86
|
+
- rubysl-pstore.gemspec
|
87
|
+
homepage: https://github.com/rubysl/rubysl-pstore
|
88
|
+
licenses:
|
89
|
+
- BSD
|
90
|
+
metadata: {}
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - '>='
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
requirements: []
|
106
|
+
rubyforge_project:
|
107
|
+
rubygems_version: 2.0.7
|
108
|
+
signing_key:
|
109
|
+
specification_version: 4
|
110
|
+
summary: Ruby standard library pstore.
|
111
|
+
test_files: []
|