storable 0.5.1
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/CHANGES.txt +14 -0
- data/LICENSE.txt +19 -0
- data/README.rdoc +52 -0
- data/Rakefile +104 -0
- data/lib/storable.rb +294 -0
- data/storable.gemspec +55 -0
- metadata +84 -0
data/CHANGES.txt
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
STORABLE, CHANGES
|
2
|
+
|
3
|
+
|
4
|
+
#### 0.5.1 (2009-05-07) #############################
|
5
|
+
|
6
|
+
* FIXED: Bug in from_hash which was incorrectly parsing some data types (incl. Integer)
|
7
|
+
* ADDED: bin/example
|
8
|
+
* ADDED: OrderedHash for Ruby 1.8.x (still unordered in JRuby. Need to investigate.)
|
9
|
+
|
10
|
+
#### 0.5 (2009-05-07) ###############################
|
11
|
+
|
12
|
+
* First public release. See commit history for solutious-stella, solutious-rudy,
|
13
|
+
and delano-delanotes for complete history of SysInfo (was SystemInfo).
|
14
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2009 Delano Mandelbaum, Solutious Inc
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
= Storable - v0.5
|
2
|
+
|
3
|
+
Marshal Ruby classes into and out of multiple formats (yaml, json, csv, tsv)
|
4
|
+
|
5
|
+
== Example
|
6
|
+
|
7
|
+
require 'storable'
|
8
|
+
|
9
|
+
class Machine < Storable
|
10
|
+
field :environment # Define field names for Machine. The
|
11
|
+
field :role # default type is String, but you can
|
12
|
+
field :position => Integer # specify a type using a hash syntax.
|
13
|
+
end
|
14
|
+
|
15
|
+
mac1 = Machine.new # Instances of Machine have accessors
|
16
|
+
mac1.environment = "stage" # just like regular attributes.
|
17
|
+
mac1.role = "app"
|
18
|
+
mac1.position = 1
|
19
|
+
|
20
|
+
puts "# YAML", mac1.to_yaml # Note: the field order is maintained
|
21
|
+
puts "# CSV", mac1.to_csv # => stage,app,1
|
22
|
+
puts "# JSON", mac1.to_json # Note: field order not maintained.
|
23
|
+
|
24
|
+
mac2 = Machine.from_yaml(mac1.to_yaml)
|
25
|
+
puts mac2.environment # => "stage"
|
26
|
+
puts mac2.position.class # => Fixnum
|
27
|
+
|
28
|
+
|
29
|
+
== Installation
|
30
|
+
|
31
|
+
Via Rubygems, one of:
|
32
|
+
|
33
|
+
$ sudo gem install storable
|
34
|
+
$ sudo gem install delano-storable --source http://gems.github.com/
|
35
|
+
|
36
|
+
or via download:
|
37
|
+
* storable-latest.tar.gz[http://github.com/delano/storable/tarball/latest]
|
38
|
+
* storable-latest.zip[http://github.com/delano/storable/zipball/latest]
|
39
|
+
|
40
|
+
|
41
|
+
== Prerequisites
|
42
|
+
|
43
|
+
* Ruby 1.8, Ruby 1.9, or JRuby 1.2
|
44
|
+
|
45
|
+
|
46
|
+
== Credits
|
47
|
+
|
48
|
+
* Delano Mandelbaum (delano@solutious.com)
|
49
|
+
|
50
|
+
== License
|
51
|
+
|
52
|
+
See: LICENSE.txt
|
data/Rakefile
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
require 'hanna/rdoctask'
|
5
|
+
require 'fileutils'
|
6
|
+
include FileUtils
|
7
|
+
|
8
|
+
task :default => :package
|
9
|
+
|
10
|
+
# CONFIG =============================================================
|
11
|
+
|
12
|
+
# Change the following according to your needs
|
13
|
+
README = "README.rdoc"
|
14
|
+
CHANGES = "CHANGES.txt"
|
15
|
+
LICENSE = "LICENSE.txt"
|
16
|
+
|
17
|
+
# Files and directories to be deleted when you run "rake clean"
|
18
|
+
CLEAN.include [ 'pkg', '*.gem', '.config']
|
19
|
+
|
20
|
+
# Virginia assumes your project and gemspec have the same name
|
21
|
+
name = (Dir.glob('*.gemspec') || ['virginia']).first.split('.').first
|
22
|
+
load "#{name}.gemspec"
|
23
|
+
version = @spec.version
|
24
|
+
|
25
|
+
# That's it! The following defaults should allow you to get started
|
26
|
+
# on other things.
|
27
|
+
|
28
|
+
|
29
|
+
# TESTS/SPECS =========================================================
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
# INSTALL =============================================================
|
34
|
+
|
35
|
+
Rake::GemPackageTask.new(@spec) do |p|
|
36
|
+
p.need_tar = true if RUBY_PLATFORM !~ /mswin/
|
37
|
+
end
|
38
|
+
|
39
|
+
task :release => [ :rdoc, :package ]
|
40
|
+
task :install => [ :rdoc, :package ] do
|
41
|
+
sh %{sudo gem install pkg/#{name}-#{version}.gem}
|
42
|
+
end
|
43
|
+
task :uninstall => [ :clean ] do
|
44
|
+
sh %{sudo gem uninstall #{name}}
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
# RUBYFORGE RELEASE / PUBLISH TASKS ==================================
|
49
|
+
|
50
|
+
if @spec.rubyforge_project
|
51
|
+
desc 'Publish website to rubyforge'
|
52
|
+
task 'publish:rdoc' => 'doc/index.html' do
|
53
|
+
sh "scp -rp doc/* rubyforge.org:/var/www/gforge-projects/#{name}/"
|
54
|
+
end
|
55
|
+
|
56
|
+
desc 'Public release to rubyforge'
|
57
|
+
task 'publish:gem' => [:package] do |t|
|
58
|
+
sh <<-end
|
59
|
+
rubyforge add_release -o Any -a #{CHANGES} -f -n #{README} #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.gem &&
|
60
|
+
rubyforge add_file -o Any -a #{CHANGES} -f -n #{README} #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.tgz
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
# RUBY DOCS TASK ==================================
|
68
|
+
|
69
|
+
Rake::RDocTask.new do |t|
|
70
|
+
t.rdoc_dir = 'doc'
|
71
|
+
t.title = @spec.summary
|
72
|
+
t.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object'
|
73
|
+
t.options << '--charset' << 'utf-8'
|
74
|
+
t.rdoc_files.include(LICENSE)
|
75
|
+
t.rdoc_files.include(README)
|
76
|
+
t.rdoc_files.include(CHANGES)
|
77
|
+
#t.rdoc_files.include('bin/*')
|
78
|
+
t.rdoc_files.include('lib/**/*.rb')
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
#Hoe.new('rspec', Spec::VERSION::STRING) do |p|
|
85
|
+
# p.summary = Spec::VERSION::SUMMARY
|
86
|
+
# p.description = "Behaviour Driven Development for Ruby."
|
87
|
+
# p.rubyforge_name = 'rspec'
|
88
|
+
# p.developer('RSpec Development Team', 'rspec-devel@rubyforge.org')
|
89
|
+
# p.extra_dev_deps = [["cucumber",">= 0.1.13"]]
|
90
|
+
# p.remote_rdoc_dir = "rspec/#{Spec::VERSION::STRING}"
|
91
|
+
# p.rspec_options = ['--options', 'spec/spec.opts']
|
92
|
+
# p.history_file = 'History.rdoc'
|
93
|
+
# p.readme_file = 'README.rdoc'
|
94
|
+
# p.post_install_message = <<-POST_INSTALL_MESSAGE
|
95
|
+
##{'*'*50}
|
96
|
+
#
|
97
|
+
# Thank you for installing rspec-#{Spec::VERSION::STRING}
|
98
|
+
#
|
99
|
+
# Please be sure to read History.rdoc and Upgrade.rdoc
|
100
|
+
# for useful information about this release.
|
101
|
+
#
|
102
|
+
#{'*'*50}
|
103
|
+
#POST_INSTALL_MESSAGE
|
104
|
+
#end
|
data/lib/storable.rb
ADDED
@@ -0,0 +1,294 @@
|
|
1
|
+
#--
|
2
|
+
# TODO: Handle nested hashes and arrays.
|
3
|
+
# TODO: to_xml, see: http://codeforpeople.com/lib/ruby/xx/xx-2.0.0/README
|
4
|
+
#++
|
5
|
+
|
6
|
+
|
7
|
+
USE_ORDERED_HASH = (RUBY_VERSION =~ /1.9/).nil?
|
8
|
+
require 'orderedhash' if USE_ORDERED_HASH
|
9
|
+
require 'json' rescue nil
|
10
|
+
|
11
|
+
require 'yaml'
|
12
|
+
require 'fileutils'
|
13
|
+
|
14
|
+
# Storable makes data available in multiple formats and can
|
15
|
+
# re-create objects from files. Fields are defined using the
|
16
|
+
# Storable.field method which tells Storable the order and
|
17
|
+
# name.
|
18
|
+
class Storable
|
19
|
+
unless defined?(SUPPORTED_FORMATS) # We can assume all are defined
|
20
|
+
VERSION = 0.5
|
21
|
+
NICE_TIME_FORMAT = "%Y-%m-%d@%H:%M:%S".freeze
|
22
|
+
SUPPORTED_FORMATS = [:tsv, :csv, :yaml, :json, :s, :string].freeze
|
23
|
+
end
|
24
|
+
|
25
|
+
# This value will be used as a default unless provided on-the-fly.
|
26
|
+
# See SUPPORTED_FORMATS for available values.
|
27
|
+
attr_reader :format
|
28
|
+
|
29
|
+
# See SUPPORTED_FORMATS for available values
|
30
|
+
def format=(v)
|
31
|
+
v &&= v.to_sym
|
32
|
+
raise "Unsupported format: #{v}" unless SUPPORTED_FORMATS.member?(v)
|
33
|
+
@format = v
|
34
|
+
end
|
35
|
+
|
36
|
+
def postprocess
|
37
|
+
end
|
38
|
+
|
39
|
+
# TODO: from_args([HASH or ordered params])
|
40
|
+
|
41
|
+
# Accepts field definitions in the one of the follow formats:
|
42
|
+
#
|
43
|
+
# field :product
|
44
|
+
# field :product => Integer
|
45
|
+
#
|
46
|
+
# The order they're defined determines the order the will be output. The fields
|
47
|
+
# data is available by the standard accessors, class.product and class.product= etc...
|
48
|
+
# The value of the field will be cast to the type (if provided) when read from a file.
|
49
|
+
# The value is not touched when the type is not provided.
|
50
|
+
def self.field(args={})
|
51
|
+
# TODO: Examine casting from: http://codeforpeople.com/lib/ruby/fattr/fattr-1.0.3/
|
52
|
+
args = {args => nil} unless args.kind_of?(Hash)
|
53
|
+
|
54
|
+
args.each_pair do |m,t|
|
55
|
+
|
56
|
+
[[:@@field_names, m], [:@@field_types, t]].each do |tuple|
|
57
|
+
class_variable_set(tuple[0], []) unless class_variable_defined?(tuple[0])
|
58
|
+
class_variable_set(tuple[0], class_variable_get(tuple[0]) << tuple[1])
|
59
|
+
end
|
60
|
+
|
61
|
+
next if method_defined?(m)
|
62
|
+
|
63
|
+
define_method(m) do instance_variable_get("@#{m}") end
|
64
|
+
define_method("#{m}=") do |val|
|
65
|
+
instance_variable_set("@#{m}",val)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns an array of field names defined by self.field
|
71
|
+
def self.field_names
|
72
|
+
class_variable_get(:@@field_names)
|
73
|
+
end
|
74
|
+
# Returns an array of field names defined by self.field
|
75
|
+
def field_names
|
76
|
+
self.class.send(:class_variable_get, :@@field_names)
|
77
|
+
end
|
78
|
+
# Returns an array of field types defined by self.field. Fields that did
|
79
|
+
# not receive a type are set to nil.
|
80
|
+
def self.field_types
|
81
|
+
class_variable_get(:@@field_types)
|
82
|
+
end
|
83
|
+
# Returns an array of field types defined by self.field. Fields that did
|
84
|
+
# not receive a type are set to nil.
|
85
|
+
def field_types
|
86
|
+
self.class.send(:class_variable_get, :@@field_types)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Dump the object data to the given format.
|
90
|
+
def dump(format=nil, with_titles=false)
|
91
|
+
format &&= format.to_sym
|
92
|
+
format ||= 's' # as in, to_s
|
93
|
+
raise "Format not defined (#{format})" unless SUPPORTED_FORMATS.member?(format)
|
94
|
+
send("to_#{format}", with_titles)
|
95
|
+
end
|
96
|
+
|
97
|
+
def to_string(*args)
|
98
|
+
to_s(*args)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Create a new instance of the object using data from file.
|
102
|
+
def self.from_file(file_path, format='yaml')
|
103
|
+
raise "Cannot read file (#{file_path})" unless File.exists?(file_path)
|
104
|
+
raise "#{self} doesn't support from_#{format}" unless self.respond_to?("from_#{format}")
|
105
|
+
format = format || File.extname(file_path).tr('.', '')
|
106
|
+
me = send("from_#{format}", read_file_to_array(file_path))
|
107
|
+
me.format = format
|
108
|
+
me
|
109
|
+
end
|
110
|
+
# Write the object data to the given file.
|
111
|
+
def to_file(file_path=nil, with_titles=true)
|
112
|
+
raise "Cannot store to nil path" if file_path.nil?
|
113
|
+
format = File.extname(file_path).tr('.', '')
|
114
|
+
format &&= format.to_sym
|
115
|
+
format ||= @format
|
116
|
+
Storable.write_file(file_path, dump(format, with_titles))
|
117
|
+
end
|
118
|
+
|
119
|
+
# Create a new instance of the object from a hash.
|
120
|
+
def self.from_hash(from={})
|
121
|
+
return nil if !from || from.empty?
|
122
|
+
me = self.new
|
123
|
+
|
124
|
+
fnames = field_names
|
125
|
+
fnames.each_with_index do |key,index|
|
126
|
+
|
127
|
+
stored_value = from[key] || from[key.to_s] # support for symbol keys and string keys
|
128
|
+
|
129
|
+
# TODO: Correct this horrible implementation (sorry, me. It's just one of those days.)
|
130
|
+
|
131
|
+
if field_types[index] == Array
|
132
|
+
((value ||= []) << stored_value).flatten
|
133
|
+
elsif field_types[index].kind_of?(Hash)
|
134
|
+
|
135
|
+
value = stored_value
|
136
|
+
else
|
137
|
+
|
138
|
+
# SimpleDB stores attribute shit as lists of values
|
139
|
+
##value = stored_value.first if stored_value.is_a?(Array) && stored_value.size == 1
|
140
|
+
value = (stored_value.is_a?(Array) && stored_value.size == 1) ? stored_value.first : stored_value
|
141
|
+
|
142
|
+
if field_types[index] == Time
|
143
|
+
value = Time.parse(value)
|
144
|
+
elsif field_types[index] == DateTime
|
145
|
+
value = DateTime.parse(value)
|
146
|
+
elsif field_types[index] == TrueClass
|
147
|
+
value = (value.to_s == "true")
|
148
|
+
elsif field_types[index] == Float
|
149
|
+
value = value.to_f
|
150
|
+
elsif field_types[index] == Integer
|
151
|
+
value = value.to_i
|
152
|
+
elsif field_types[index].kind_of?(Storable) && stored_value.kind_of?(Hash)
|
153
|
+
# I don't know why this is here so I'm going to raise an exception
|
154
|
+
# and wait a while for an error in one of my other projects.
|
155
|
+
#value = field_types[index].from_hash(stored_value)
|
156
|
+
raise "Delano, delano, delano. Clean up Storable!"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
me.send("#{key}=", value) if self.method_defined?("#{key}=")
|
161
|
+
end
|
162
|
+
|
163
|
+
me.postprocess
|
164
|
+
|
165
|
+
me
|
166
|
+
end
|
167
|
+
# Return the object data as a hash
|
168
|
+
# +with_titles+ is ignored.
|
169
|
+
def to_hash(with_titles=true)
|
170
|
+
tmp = USE_ORDERED_HASH ? OrderedHash.new : {}
|
171
|
+
field_names.each do |fname|
|
172
|
+
tmp[fname] = self.send(fname)
|
173
|
+
end
|
174
|
+
tmp
|
175
|
+
end
|
176
|
+
|
177
|
+
# Create a new instance of the object from YAML.
|
178
|
+
# +from+ a YAML String or Array (split into by line).
|
179
|
+
def self.from_yaml(*from)
|
180
|
+
from_str = [from].flatten.compact.join('')
|
181
|
+
hash = YAML::load(from_str)
|
182
|
+
hash = from_hash(hash) if hash.kind_of?(Hash)
|
183
|
+
hash
|
184
|
+
end
|
185
|
+
def to_yaml(with_titles=true)
|
186
|
+
to_hash.to_yaml
|
187
|
+
end
|
188
|
+
|
189
|
+
# Create a new instance of the object from a JSON string.
|
190
|
+
# +from+ a JSON string split into an array by line.
|
191
|
+
def self.from_json(from=[])
|
192
|
+
# from is an array of strings
|
193
|
+
from_str = from.join('')
|
194
|
+
tmp = JSON::load(from_str)
|
195
|
+
hash_sym = tmp.keys.inject({}) do |hash, key|
|
196
|
+
hash[key.to_sym] = tmp[key]
|
197
|
+
hash
|
198
|
+
end
|
199
|
+
hash_sym = from_hash(hash_sym) if hash_sym.kind_of?(Hash)
|
200
|
+
hash_sym
|
201
|
+
end
|
202
|
+
def to_json(with_titles=true)
|
203
|
+
to_hash.to_json
|
204
|
+
end
|
205
|
+
|
206
|
+
# Return the object data as a delimited string.
|
207
|
+
# +with_titles+ specifiy whether to include field names (default: false)
|
208
|
+
# +delim+ is the field delimiter.
|
209
|
+
def to_delimited(with_titles=false, delim=',')
|
210
|
+
values = []
|
211
|
+
field_names.each do |fname|
|
212
|
+
values << self.send(fname.to_s) # TODO: escape values
|
213
|
+
end
|
214
|
+
output = values.join(delim)
|
215
|
+
output = field_names.join(delim) << $/ << output if with_titles
|
216
|
+
output
|
217
|
+
end
|
218
|
+
# Return the object data as a tab delimited string.
|
219
|
+
# +with_titles+ specifiy whether to include field names (default: false)
|
220
|
+
def to_tsv(with_titles=false)
|
221
|
+
to_delimited(with_titles, "\t")
|
222
|
+
end
|
223
|
+
# Return the object data as a comma delimited string.
|
224
|
+
# +with_titles+ specifiy whether to include field names (default: false)
|
225
|
+
def to_csv(with_titles=false)
|
226
|
+
to_delimited(with_titles, ',')
|
227
|
+
end
|
228
|
+
# Create a new instance from tab-delimited data.
|
229
|
+
# +from+ a JSON string split into an array by line.
|
230
|
+
def self.from_tsv(from=[])
|
231
|
+
self.from_delimited(from, "\t")
|
232
|
+
end
|
233
|
+
# Create a new instance of the object from comma-delimited data.
|
234
|
+
# +from+ a JSON string split into an array by line.
|
235
|
+
def self.from_csv(from=[])
|
236
|
+
self.from_delimited(from, ',')
|
237
|
+
end
|
238
|
+
|
239
|
+
# Create a new instance of the object from a delimited string.
|
240
|
+
# +from+ a JSON string split into an array by line.
|
241
|
+
# +delim+ is the field delimiter.
|
242
|
+
def self.from_delimited(from=[],delim=',')
|
243
|
+
return if from.empty?
|
244
|
+
# We grab an instance of the class so we can
|
245
|
+
hash = {}
|
246
|
+
|
247
|
+
fnames = values = []
|
248
|
+
if (from.size > 1 && !from[1].empty?)
|
249
|
+
fnames = from[0].chomp.split(delim)
|
250
|
+
values = from[1].chomp.split(delim)
|
251
|
+
else
|
252
|
+
fnames = self.field_names
|
253
|
+
values = from[0].chomp.split(delim)
|
254
|
+
end
|
255
|
+
|
256
|
+
fnames.each_with_index do |key,index|
|
257
|
+
next unless values[index]
|
258
|
+
hash[key.to_sym] = values[index]
|
259
|
+
end
|
260
|
+
hash = from_hash(hash) if hash.kind_of?(Hash)
|
261
|
+
hash
|
262
|
+
end
|
263
|
+
|
264
|
+
def self.read_file_to_array(path)
|
265
|
+
contents = []
|
266
|
+
return contents unless File.exists?(path)
|
267
|
+
|
268
|
+
open(path, 'r') do |l|
|
269
|
+
contents = l.readlines
|
270
|
+
end
|
271
|
+
|
272
|
+
contents
|
273
|
+
end
|
274
|
+
|
275
|
+
def self.write_file(path, content, flush=true)
|
276
|
+
write_or_append_file('w', path, content, flush)
|
277
|
+
end
|
278
|
+
|
279
|
+
def self.append_file(path, content, flush=true)
|
280
|
+
write_or_append_file('a', path, content, flush)
|
281
|
+
end
|
282
|
+
|
283
|
+
def self.write_or_append_file(write_or_append, path, content = '', flush = true)
|
284
|
+
#STDERR.puts "Writing to #{ path }..."
|
285
|
+
create_dir(File.dirname(path))
|
286
|
+
|
287
|
+
open(path, write_or_append) do |f|
|
288
|
+
f.puts content
|
289
|
+
f.flush if flush;
|
290
|
+
end
|
291
|
+
File.chmod(0600, path)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
data/storable.gemspec
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
@spec = Gem::Specification.new do |s|
|
2
|
+
s.name = "storable"
|
3
|
+
s.rubyforge_project = "storable"
|
4
|
+
s.version = "0.5.1"
|
5
|
+
s.summary = "Storable: Marshal Ruby classes into and out of multiple formats (yaml, json, csv, tsv)"
|
6
|
+
s.description = s.summary
|
7
|
+
s.author = "Delano Mandelbaum"
|
8
|
+
s.email = "delano@solutious.com"
|
9
|
+
s.homepage = "http://solutious.com/"
|
10
|
+
|
11
|
+
|
12
|
+
# = EXECUTABLES =
|
13
|
+
# The list of executables in your project (if any). Don't include the path,
|
14
|
+
# just the base filename.
|
15
|
+
s.executables = %w[]
|
16
|
+
|
17
|
+
# = DEPENDENCIES =
|
18
|
+
# Add all gem dependencies
|
19
|
+
s.add_dependency 'sysinfo', '>= 0.5.0'
|
20
|
+
|
21
|
+
# = MANIFEST =
|
22
|
+
# The complete list of files to be included in the release. When GitHub packages your gem,
|
23
|
+
# it doesn't allow you to run any command that accesses the filesystem. You will get an
|
24
|
+
# error. You can ask your VCS for the list of versioned files:
|
25
|
+
# git ls-files
|
26
|
+
# svn list -R
|
27
|
+
s.files = %w(
|
28
|
+
CHANGES.txt
|
29
|
+
LICENSE.txt
|
30
|
+
README.rdoc
|
31
|
+
Rakefile
|
32
|
+
lib/storable.rb
|
33
|
+
storable.gemspec
|
34
|
+
)
|
35
|
+
|
36
|
+
s.extra_rdoc_files = %w[README.rdoc LICENSE.txt]
|
37
|
+
s.has_rdoc = true
|
38
|
+
s.rdoc_options = ["--line-numbers", "--title", s.summary, "--main", "README.rdoc"]
|
39
|
+
s.require_paths = %w[lib]
|
40
|
+
s.rubygems_version = '1.3.0'
|
41
|
+
|
42
|
+
if s.respond_to? :specification_version then
|
43
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
44
|
+
s.specification_version = 2
|
45
|
+
|
46
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
47
|
+
s.add_runtime_dependency(%q<RedCloth>, [">= 4.0.4"])
|
48
|
+
else
|
49
|
+
s.add_dependency(%q<RedCloth>, [">= 4.0.4"])
|
50
|
+
end
|
51
|
+
else
|
52
|
+
s.add_dependency(%q<RedCloth>, [">= 4.0.4"])
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: storable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Delano Mandelbaum
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-05-07 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: sysinfo
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.5.0
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: RedCloth
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 4.0.4
|
34
|
+
version:
|
35
|
+
description: "Storable: Marshal Ruby classes into and out of multiple formats (yaml, json, csv, tsv)"
|
36
|
+
email: delano@solutious.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.rdoc
|
43
|
+
- LICENSE.txt
|
44
|
+
files:
|
45
|
+
- CHANGES.txt
|
46
|
+
- LICENSE.txt
|
47
|
+
- README.rdoc
|
48
|
+
- Rakefile
|
49
|
+
- lib/storable.rb
|
50
|
+
- storable.gemspec
|
51
|
+
has_rdoc: true
|
52
|
+
homepage: http://solutious.com/
|
53
|
+
licenses: []
|
54
|
+
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options:
|
57
|
+
- --line-numbers
|
58
|
+
- --title
|
59
|
+
- "Storable: Marshal Ruby classes into and out of multiple formats (yaml, json, csv, tsv)"
|
60
|
+
- --main
|
61
|
+
- README.rdoc
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "0"
|
75
|
+
version:
|
76
|
+
requirements: []
|
77
|
+
|
78
|
+
rubyforge_project: storable
|
79
|
+
rubygems_version: 1.3.2
|
80
|
+
signing_key:
|
81
|
+
specification_version: 2
|
82
|
+
summary: "Storable: Marshal Ruby classes into and out of multiple formats (yaml, json, csv, tsv)"
|
83
|
+
test_files: []
|
84
|
+
|