storable 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|