ledis 0.0.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.
Files changed (5) hide show
  1. data/README.md +56 -0
  2. data/Rakefile +374 -0
  3. data/ledis.gemspec +29 -0
  4. data/lib/ledis.rb +259 -0
  5. metadata +48 -0
@@ -0,0 +1,56 @@
1
+ NAME
2
+
3
+ ledis
4
+
5
+
6
+ SYNOPSIS
7
+
8
+ a K.I.S.S auto-rotating redis logger for ruby/rails
9
+
10
+ Ruby
11
+
12
+ redis = Redis.new
13
+
14
+ logger = Ledis.logger redis
15
+
16
+ logger = Ledis.new
17
+
18
+ logger = Ledis.new do |config|
19
+
20
+ config.redis = Redis.new
21
+
22
+ config.list = 'teh_foo:log'
23
+
24
+ config.cap = 2 ** 16
25
+
26
+ end
27
+
28
+ Rails
29
+
30
+ ### file: config/environments/development.rb
31
+
32
+ config.logger = Ledis.logger do |logger|
33
+
34
+ logger.list = "teh_rails_app:#{ Rails.env }:log"
35
+
36
+ end
37
+
38
+
39
+ DESCRIPTION
40
+
41
+ ledis logs yo shiznit to redis. it's got built in logic to auto-truncate
42
+ logs when they get to big
43
+
44
+ logger.truncate(2 **16)
45
+
46
+ and to grab the most recent ones
47
+
48
+ puts logger.tail(1024)
49
+
50
+ it's list/line oriented, just like a log file and makes no attempt to
51
+ annotated log lines or add fancy data structures to them
52
+
53
+ INSTALL
54
+
55
+ gem 'ledis'
56
+
@@ -0,0 +1,374 @@
1
+ This.rubyforge_project = 'codeforpeople'
2
+ This.author = "Ara T. Howard"
3
+ This.email = "ara.t.howard@gmail.com"
4
+ This.homepage = "https://github.com/ahoward/#{ This.lib }"
5
+
6
+ task :license do
7
+ open('LICENSE', 'w'){|fd| fd.puts "same as ruby's"}
8
+ end
9
+
10
+ task :default do
11
+ puts((Rake::Task.tasks.map{|task| task.name.gsub(/::/,':')} - ['default']).sort)
12
+ end
13
+
14
+ task :test do
15
+ run_tests!
16
+ end
17
+
18
+ namespace :test do
19
+ task(:unit){ run_tests!(:unit) }
20
+ task(:functional){ run_tests!(:functional) }
21
+ task(:integration){ run_tests!(:integration) }
22
+ end
23
+
24
+ def run_tests!(which = nil)
25
+ which ||= '**'
26
+ test_dir = File.join(This.dir, "test")
27
+ test_glob ||= File.join(test_dir, "#{ which }/**_test.rb")
28
+ test_rbs = Dir.glob(test_glob).sort
29
+
30
+ div = ('=' * 119)
31
+ line = ('-' * 119)
32
+
33
+ test_rbs.each_with_index do |test_rb, index|
34
+ testno = index + 1
35
+ command = "#{ This.ruby } -I ./lib -I ./test/lib #{ test_rb }"
36
+
37
+ puts
38
+ say(div, :color => :cyan, :bold => true)
39
+ say("@#{ testno } => ", :bold => true, :method => :print)
40
+ say(command, :color => :cyan, :bold => true)
41
+ say(line, :color => :cyan, :bold => true)
42
+
43
+ system(command)
44
+
45
+ say(line, :color => :cyan, :bold => true)
46
+
47
+ status = $?.exitstatus
48
+
49
+ if status.zero?
50
+ say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
51
+ say("SUCCESS", :color => :green, :bold => true)
52
+ else
53
+ say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
54
+ say("FAILURE", :color => :red, :bold => true)
55
+ end
56
+ say(line, :color => :cyan, :bold => true)
57
+
58
+ exit(status) unless status.zero?
59
+ end
60
+ end
61
+
62
+
63
+ task :gemspec do
64
+ ignore_extensions = ['git', 'svn', 'tmp', /sw./, 'bak', 'gem']
65
+ ignore_directories = ['pkg']
66
+ ignore_files = ['test/log']
67
+
68
+ shiteless =
69
+ lambda do |list|
70
+ list.delete_if do |entry|
71
+ next unless test(?e, entry)
72
+ extension = File.basename(entry).split(%r/[.]/).last
73
+ ignore_extensions.any?{|ext| ext === extension}
74
+ end
75
+ list.delete_if do |entry|
76
+ next unless test(?d, entry)
77
+ dirname = File.expand_path(entry)
78
+ ignore_directories.any?{|dir| File.expand_path(dir) == dirname}
79
+ end
80
+ list.delete_if do |entry|
81
+ next unless test(?f, entry)
82
+ filename = File.expand_path(entry)
83
+ ignore_files.any?{|file| File.expand_path(file) == filename}
84
+ end
85
+ end
86
+
87
+ lib = This.lib
88
+ object = This.object
89
+ version = This.version
90
+ files = shiteless[Dir::glob("**/**")]
91
+ executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
92
+ #has_rdoc = true #File.exist?('doc')
93
+ test_files = "test/#{ lib }.rb" if File.file?("test/#{ lib }.rb")
94
+ summary = object.respond_to?(:summary) ? object.summary : "summary: #{ lib } kicks the ass"
95
+ description = object.respond_to?(:description) ? object.description : "description: #{ lib } kicks the ass"
96
+
97
+ if This.extensions.nil?
98
+ This.extensions = []
99
+ extensions = This.extensions
100
+ %w( Makefile configure extconf.rb ).each do |ext|
101
+ extensions << ext if File.exists?(ext)
102
+ end
103
+ end
104
+ extensions = [extensions].flatten.compact
105
+
106
+ template =
107
+ if test(?e, 'gemspec.erb')
108
+ Template{ IO.read('gemspec.erb') }
109
+ else
110
+ Template {
111
+ <<-__
112
+ ## #{ lib }.gemspec
113
+ #
114
+
115
+ Gem::Specification::new do |spec|
116
+ spec.name = #{ lib.inspect }
117
+ spec.version = #{ version.inspect }
118
+ spec.platform = Gem::Platform::RUBY
119
+ spec.summary = #{ lib.inspect }
120
+ spec.description = #{ description.inspect }
121
+
122
+ spec.files =\n#{ files.sort.pretty_inspect }
123
+ spec.executables = #{ executables.inspect }
124
+
125
+ spec.require_path = "lib"
126
+
127
+ spec.test_files = #{ test_files.inspect }
128
+
129
+ ### spec.add_dependency 'lib', '>= version'
130
+ #### spec.add_dependency 'map'
131
+
132
+ spec.extensions.push(*#{ extensions.inspect })
133
+
134
+ spec.rubyforge_project = #{ This.rubyforge_project.inspect }
135
+ spec.author = #{ This.author.inspect }
136
+ spec.email = #{ This.email.inspect }
137
+ spec.homepage = #{ This.homepage.inspect }
138
+ end
139
+ __
140
+ }
141
+ end
142
+
143
+ Fu.mkdir_p(This.pkgdir)
144
+ gemspec = "#{ lib }.gemspec"
145
+ open(gemspec, "w"){|fd| fd.puts(template)}
146
+ This.gemspec = gemspec
147
+ end
148
+
149
+ task :gem => [:clean, :gemspec] do
150
+ Fu.mkdir_p(This.pkgdir)
151
+ before = Dir['*.gem']
152
+ cmd = "gem build #{ This.gemspec }"
153
+ `#{ cmd }`
154
+ after = Dir['*.gem']
155
+ gem = ((after - before).first || after.first) or abort('no gem!')
156
+ Fu.mv(gem, This.pkgdir)
157
+ This.gem = File.join(This.pkgdir, File.basename(gem))
158
+ end
159
+
160
+ task :readme do
161
+ samples = ''
162
+ prompt = '~ > '
163
+ lib = This.lib
164
+ version = This.version
165
+
166
+ Dir['sample*/*'].sort.each do |sample|
167
+ samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
168
+
169
+ cmd = "cat #{ sample }"
170
+ samples << Util.indent(prompt + cmd, 2) << "\n\n"
171
+ samples << Util.indent(`#{ cmd }`, 4) << "\n"
172
+
173
+ cmd = "ruby #{ sample }"
174
+ samples << Util.indent(prompt + cmd, 2) << "\n\n"
175
+
176
+ cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -I ./lib #{ sample })'"
177
+ samples << Util.indent(`#{ cmd } 2>&1`, 4) << "\n"
178
+ end
179
+
180
+ template =
181
+ if test(?e, 'readme.erb')
182
+ Template{ IO.read('readme.erb') }
183
+ else
184
+ Template {
185
+ <<-__
186
+ NAME
187
+ #{ lib }
188
+
189
+ DESCRIPTION
190
+
191
+ INSTALL
192
+ gem install #{ lib }
193
+
194
+ SAMPLES
195
+ #{ samples }
196
+ __
197
+ }
198
+ end
199
+
200
+ open("README", "w"){|fd| fd.puts template}
201
+ end
202
+
203
+
204
+ task :clean do
205
+ Dir[File.join(This.pkgdir, '**/**')].each{|entry| Fu.rm_rf(entry)}
206
+ end
207
+
208
+
209
+ task :release => [:clean, :gemspec, :gem] do
210
+ gems = Dir[File.join(This.pkgdir, '*.gem')].flatten
211
+ raise "which one? : #{ gems.inspect }" if gems.size > 1
212
+ raise "no gems?" if gems.size < 1
213
+
214
+ cmd = "gem push #{ This.gem }"
215
+ puts cmd
216
+ puts
217
+ system(cmd)
218
+ abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
219
+
220
+ cmd = "rubyforge login && rubyforge add_release #{ This.rubyforge_project } #{ This.lib } #{ This.version } #{ This.gem }"
221
+ puts cmd
222
+ puts
223
+ system(cmd)
224
+ abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
225
+ end
226
+
227
+
228
+
229
+
230
+
231
+ BEGIN {
232
+ # support for this rakefile
233
+ #
234
+ $VERBOSE = nil
235
+
236
+ require 'ostruct'
237
+ require 'erb'
238
+ require 'fileutils'
239
+ require 'rbconfig'
240
+ require 'pp'
241
+
242
+ # fu shortcut
243
+ #
244
+ Fu = FileUtils
245
+
246
+ # cache a bunch of stuff about this rakefile/environment
247
+ #
248
+ This = OpenStruct.new
249
+
250
+ This.file = File.expand_path(__FILE__)
251
+ This.dir = File.dirname(This.file)
252
+ This.pkgdir = File.join(This.dir, 'pkg')
253
+
254
+ # grok lib
255
+ #
256
+ lib = ENV['LIB']
257
+ unless lib
258
+ lib = File.basename(Dir.pwd).sub(/[-].*$/, '')
259
+ end
260
+ This.lib = lib
261
+
262
+ # grok version
263
+ #
264
+ version = ENV['VERSION']
265
+ unless version
266
+ require "./lib/#{ This.lib }"
267
+ This.name = lib.capitalize
268
+ This.object = eval(This.name)
269
+ version = This.object.send(:version)
270
+ end
271
+ This.version = version
272
+
273
+ # we need to know the name of the lib an it's version
274
+ #
275
+ abort('no lib') unless This.lib
276
+ abort('no version') unless This.version
277
+
278
+ # discover full path to this ruby executable
279
+ #
280
+ c = Config::CONFIG
281
+ bindir = c["bindir"] || c['BINDIR']
282
+ ruby_install_name = c['ruby_install_name'] || c['RUBY_INSTALL_NAME'] || 'ruby'
283
+ ruby_ext = c['EXEEXT'] || ''
284
+ ruby = File.join(bindir, (ruby_install_name + ruby_ext))
285
+ This.ruby = ruby
286
+
287
+ # some utils
288
+ #
289
+ module Util
290
+ def indent(s, n = 2)
291
+ s = unindent(s)
292
+ ws = ' ' * n
293
+ s.gsub(%r/^/, ws)
294
+ end
295
+
296
+ def unindent(s)
297
+ indent = nil
298
+ s.each_line do |line|
299
+ next if line =~ %r/^\s*$/
300
+ indent = line[%r/^\s*/] and break
301
+ end
302
+ indent ? s.gsub(%r/^#{ indent }/, "") : s
303
+ end
304
+ extend self
305
+ end
306
+
307
+ # template support
308
+ #
309
+ class Template
310
+ def initialize(&block)
311
+ @block = block
312
+ @template = block.call.to_s
313
+ end
314
+ def expand(b=nil)
315
+ ERB.new(Util.unindent(@template)).result((b||@block).binding)
316
+ end
317
+ alias_method 'to_s', 'expand'
318
+ end
319
+ def Template(*args, &block) Template.new(*args, &block) end
320
+
321
+ # colored console output support
322
+ #
323
+ This.ansi = {
324
+ :clear => "\e[0m",
325
+ :reset => "\e[0m",
326
+ :erase_line => "\e[K",
327
+ :erase_char => "\e[P",
328
+ :bold => "\e[1m",
329
+ :dark => "\e[2m",
330
+ :underline => "\e[4m",
331
+ :underscore => "\e[4m",
332
+ :blink => "\e[5m",
333
+ :reverse => "\e[7m",
334
+ :concealed => "\e[8m",
335
+ :black => "\e[30m",
336
+ :red => "\e[31m",
337
+ :green => "\e[32m",
338
+ :yellow => "\e[33m",
339
+ :blue => "\e[34m",
340
+ :magenta => "\e[35m",
341
+ :cyan => "\e[36m",
342
+ :white => "\e[37m",
343
+ :on_black => "\e[40m",
344
+ :on_red => "\e[41m",
345
+ :on_green => "\e[42m",
346
+ :on_yellow => "\e[43m",
347
+ :on_blue => "\e[44m",
348
+ :on_magenta => "\e[45m",
349
+ :on_cyan => "\e[46m",
350
+ :on_white => "\e[47m"
351
+ }
352
+ def say(phrase, *args)
353
+ options = args.last.is_a?(Hash) ? args.pop : {}
354
+ options[:color] = args.shift.to_s.to_sym unless args.empty?
355
+ keys = options.keys
356
+ keys.each{|key| options[key.to_s.to_sym] = options.delete(key)}
357
+
358
+ color = options[:color]
359
+ bold = options.has_key?(:bold)
360
+
361
+ parts = [phrase]
362
+ parts.unshift(This.ansi[color]) if color
363
+ parts.unshift(This.ansi[:bold]) if bold
364
+ parts.push(This.ansi[:clear]) if parts.size > 1
365
+
366
+ method = options[:method] || :puts
367
+
368
+ Kernel.send(method, parts.join)
369
+ end
370
+
371
+ # always run out of the project dir
372
+ #
373
+ Dir.chdir(This.dir)
374
+ }
@@ -0,0 +1,29 @@
1
+ ## ledis.gemspec
2
+ #
3
+
4
+ Gem::Specification::new do |spec|
5
+ spec.name = "ledis"
6
+ spec.version = "0.0.1"
7
+ spec.platform = Gem::Platform::RUBY
8
+ spec.summary = "ledis"
9
+ spec.description = "description: ledis kicks the ass"
10
+
11
+ spec.files =
12
+ ["README.md", "Rakefile", "ledis.gemspec", "lib", "lib/ledis.rb"]
13
+
14
+ spec.executables = []
15
+
16
+ spec.require_path = "lib"
17
+
18
+ spec.test_files = nil
19
+
20
+ ### spec.add_dependency 'lib', '>= version'
21
+ #### spec.add_dependency 'map'
22
+
23
+ spec.extensions.push(*[])
24
+
25
+ spec.rubyforge_project = "codeforpeople"
26
+ spec.author = "Ara T. Howard"
27
+ spec.email = "ara.t.howard@gmail.com"
28
+ spec.homepage = "https://github.com/ahoward/ledis"
29
+ end
@@ -0,0 +1,259 @@
1
+ # -*- encoding : utf-8 -*-
2
+ #
3
+ # NAME
4
+ #
5
+ # ledis
6
+ #
7
+ #
8
+ # SYNOPSIS
9
+ #
10
+ # a K.I.S.S auto-rotating redis logger for ruby/rails
11
+ #
12
+ # Ruby
13
+ #
14
+ # redis = Redis.new
15
+ #
16
+ # logger = Ledis.logger redis
17
+ #
18
+ # logger = Ledis.new
19
+ #
20
+ # logger = Ledis.new do |config|
21
+ #
22
+ # config.redis = Redis.new
23
+ #
24
+ # config.list = 'teh_foo:log'
25
+ #
26
+ # config.cap = 2 ** 16
27
+ #
28
+ # end
29
+ #
30
+ # Rails
31
+ #
32
+ # ### file: config/environments/development.rb
33
+ #
34
+ # config.logger = Ledis.logger do |logger|
35
+ #
36
+ # logger.list = "teh_rails_app:#{ Rails.env }:log"
37
+ #
38
+ # end
39
+ #
40
+ #
41
+ # DESCRIPTION
42
+ #
43
+ # ledis logs yo shiznit to redis. it's got built in logic to auto-truncate
44
+ # logs when they get to big
45
+ #
46
+ # logger.truncate(2 **16)
47
+ #
48
+ # and to grab the most recent ones
49
+ #
50
+ # puts logger.tail(1024)
51
+ #
52
+ # it's list/line oriented, just like a log file and makes no attempt to
53
+ # annotated log lines or add fancy data structures to them
54
+ #
55
+ # INSTALL
56
+ #
57
+ # gem 'ledis'
58
+ #
59
+
60
+ require 'logger'
61
+
62
+ module Ledis
63
+ ##
64
+ #
65
+ class << Ledis
66
+ def version
67
+ '0.0.1'
68
+ end
69
+
70
+ def dependencies
71
+ {
72
+ 'map' => [ 'map' , ' >= 6.0.1' ],
73
+ 'redis' => [ 'redis' , ' >= 2.2.2' ]
74
+ }
75
+ end
76
+ end
77
+
78
+ begin
79
+ require 'rubygems'
80
+ rescue LoadError
81
+ nil
82
+ end
83
+
84
+ dependencies.each do |lib, dependency|
85
+ gem(*dependency) if defined?(gem)
86
+ require(lib)
87
+ end
88
+
89
+ ##
90
+ #
91
+ class << Ledis
92
+ def logger(*args, &block)
93
+ return rails_logger(*args, &block) if defined?(::Rails.application)
94
+
95
+ Logger.new(*args, &block)
96
+ end
97
+
98
+ def rails_logger(*args, &block)
99
+ config = ::Rails.application.config
100
+
101
+ logger = Logger.new(*args, &block)
102
+
103
+ if defined?(::ActiveSupport::TaggedLogging)
104
+ logger = ::ActiveSupport::TaggedLogging.new(logger)
105
+ end
106
+
107
+ logger.level = config.log_level
108
+
109
+ logger
110
+ end
111
+ end
112
+
113
+ ##
114
+ #
115
+ class Logger < ::Logger
116
+ #
117
+ attr_accessor :logdev
118
+ attr_accessor :formatter
119
+
120
+ def initialize(*args, &block)
121
+ super(STDERR)
122
+ @logdev = LogDevice.new(*args, &block)
123
+ @formatter = Formatter.new
124
+ end
125
+
126
+ class Formatter < ::Logger::Formatter
127
+ Format = "%s, [%s#%d] %5s : %s\n"
128
+
129
+ def call(severity, time, progname, msg)
130
+ Format %
131
+ [severity[0..0], format_datetime(time), $$, severity, msg2str(msg)]
132
+ end
133
+ end
134
+
135
+ def << (*args)
136
+ super
137
+ self
138
+ end
139
+
140
+ def level=(level)
141
+ @level = level_for(level)
142
+ end
143
+
144
+ Levels =
145
+ Hash[ Severity.constants.map{|c| [c.to_s.downcase, Severity.const_get(c)]} ]
146
+
147
+ def level_for(level)
148
+ case level
149
+ when Integer
150
+ Levels[ Levels.invert[level] || 4 ]
151
+ else
152
+ Levels[ level.to_s.downcase ]
153
+ end
154
+ end
155
+
156
+ %w(
157
+ redis redis=
158
+ list list=
159
+ cap cap=
160
+ step step=
161
+ cycle cycle=
162
+ tail
163
+ truncate
164
+ size
165
+ ).each do |method|
166
+ case method
167
+ when /=/
168
+ class_eval <<-__, __FILE__, __LINE__
169
+ def #{ method }(arg)
170
+ @logdev.#{ method }(arg)
171
+ end
172
+ __
173
+
174
+ else
175
+ class_eval <<-__, __FILE__, __LINE__
176
+ def #{ method }(*args, &block)
177
+ @logdev.#{ method }(*args, &block)
178
+ end
179
+ __
180
+ end
181
+ end
182
+
183
+ ##
184
+ #
185
+ class LogDevice
186
+ attr_accessor :config
187
+ attr_accessor :cap
188
+ attr_accessor :step
189
+ attr_accessor :cycle
190
+ attr_accessor :list
191
+
192
+ def initialize(*args, &block)
193
+ config = Map.options_for!(args)
194
+ config[:redis] ||= args.shift
195
+ configure(config, &block)
196
+ end
197
+
198
+ def configure(config = {}, &block)
199
+ @config = Map.for(config)
200
+
201
+ block.call(@config) if block
202
+
203
+ @redis = @config[:redis] || @redis
204
+ @cap = @config[:cap] || (2 ** 16)
205
+ @step = @config[:step] || 0
206
+ @cycle = @config[:cycle] || (2 ** 8)
207
+ @list = @config[:list] || 'ledis:log'
208
+ end
209
+
210
+ def redis
211
+ @redis ||= Redis.new
212
+ end
213
+
214
+ def redis=(redis)
215
+ @redis = redis
216
+ end
217
+
218
+ def write(message)
219
+ begin
220
+ redis.lpush(list, message)
221
+ rescue Object => e
222
+ error = "#{ e.message } (#{ e.class })\n#{ Array(e.backtrace).join(10.chr) }"
223
+ STDERR.puts(error)
224
+ STDERR.puts(message)
225
+ end
226
+ ensure
227
+ if (@step % @cycle).zero?
228
+ truncate(@cap) rescue nil
229
+ end
230
+ @step = (@step + 1) % @cycle
231
+ end
232
+
233
+ if defined?(Rails::Server) and STDOUT.tty? and not defined?(ActiveSupport::Logger.broadcast)
234
+ alias_method('__write__', 'write')
235
+
236
+ def write(message, &block)
237
+ STDOUT.puts(message)
238
+ __write__(message, &block)
239
+ end
240
+ end
241
+
242
+ def close
243
+ redis.quit rescue nil
244
+ end
245
+
246
+ def tail(n = 1024)
247
+ redis.lrange(list, 0, n - 1).reverse
248
+ end
249
+
250
+ def truncate(size)
251
+ redis.ltrim(list, 0, size - 1)
252
+ end
253
+
254
+ def size
255
+ redis.llen(list)
256
+ end
257
+ end
258
+ end
259
+ end
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ledis
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ara T. Howard
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-15 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: ! 'description: ledis kicks the ass'
15
+ email: ara.t.howard@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - README.md
21
+ - Rakefile
22
+ - ledis.gemspec
23
+ - lib/ledis.rb
24
+ homepage: https://github.com/ahoward/ledis
25
+ licenses: []
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ! '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project: codeforpeople
44
+ rubygems_version: 1.8.23
45
+ signing_key:
46
+ specification_version: 3
47
+ summary: ledis
48
+ test_files: []