upload_cache 1.4.1 → 2.2.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.
data/Rakefile CHANGED
@@ -29,7 +29,8 @@ def run_tests!(which = nil)
29
29
 
30
30
  test_rbs.each_with_index do |test_rb, index|
31
31
  testno = index + 1
32
- command = "#{ This.ruby } -I ./lib -I ./test/lib #{ test_rb }"
32
+ test_rb.gsub!(/#{ Regexp.escape(This.dir) }/, '.')
33
+ command = "#{ File.basename(This.ruby) } -I./lib -I./test/lib #{ test_rb }"
33
34
 
34
35
  puts
35
36
  say(div, :color => :cyan, :bold => true)
@@ -59,9 +60,14 @@ end
59
60
 
60
61
  task :gemspec do
61
62
  ignore_extensions = ['git', 'svn', 'tmp', /sw./, 'bak', 'gem']
62
- ignore_directories = ['pkg']
63
+ ignore_directories = ['pkg', 'test/tmp', 'tmp']
63
64
  ignore_files = ['test/log', 'a.rb'] + Dir['db/*'] + %w'db'
64
65
 
66
+ root = File.expand_path(File.dirname(__FILE__))
67
+
68
+ ignore_directories.map!{|_| File.join(root, _)}
69
+ ignore_files.map!{|_| File.join(root, _)}
70
+
65
71
  shiteless =
66
72
  lambda do |list|
67
73
  list.delete_if do |entry|
@@ -69,16 +75,15 @@ task :gemspec do
69
75
  extension = File.basename(entry).split(%r/[.]/).last
70
76
  ignore_extensions.any?{|ext| ext === extension}
71
77
  end
72
- list.delete_if do |entry|
73
- next unless test(?d, entry)
74
- dirname = File.expand_path(entry)
75
- ignore_directories.any?{|dir| File.expand_path(dir) == dirname}
76
- end
77
78
  list.delete_if do |entry|
78
79
  next unless test(?f, entry)
79
80
  filename = File.expand_path(entry)
80
81
  ignore_files.any?{|file| File.expand_path(file) == filename}
81
82
  end
83
+ list.delete_if do |entry|
84
+ dirname = File.expand_path(entry)
85
+ ignore_directories.any?{|dir| dirname[dir]}
86
+ end
82
87
  end
83
88
 
84
89
  lib = This.lib
@@ -5,7 +5,7 @@ require 'tmpdir'
5
5
  require 'map'
6
6
 
7
7
  class UploadCache
8
- Version = '1.4.1'
8
+ Version = '2.2.0'
9
9
 
10
10
  Readme = <<-__
11
11
  NAME
@@ -61,6 +61,7 @@ class UploadCache
61
61
  UploadCache::Version
62
62
  end
63
63
 
64
+
64
65
  def url
65
66
  @url ||= (
66
67
  if defined?(Rails.root) and Rails.root
@@ -128,7 +129,7 @@ class UploadCache
128
129
 
129
130
  def finalizer(object_id)
130
131
  if fd = IOs[object_id]
131
- IO.for_fd(fd).close
132
+ ::IO.for_fd(fd).close rescue nil
132
133
  IOs.delete(object_id)
133
134
  end
134
135
  end
@@ -187,75 +188,160 @@ class UploadCache
187
188
  @prefix
188
189
  end
189
190
 
190
- def prefix=(value)
191
- @prefix = value
192
- end
193
-
194
191
  def default
195
192
  @default ||= Map[:url, nil, :path, nil]
196
193
  end
197
194
 
198
- def for(params, *args)
199
- params = Map.for(params)
195
+ def prefix=(value)
196
+ @prefix = value
197
+ end
198
+
199
+ def cache(params, *args)
200
+ params_map = Map.for(params)
200
201
  options = Map.options_for!(args)
201
202
 
202
203
  key = Array(options[:key] || args).flatten.compact
203
204
  key = [:upload] if key.empty?
204
205
 
205
- return(
206
- currently_uploaded_file(params, key, options) or
207
- previously_uploaded_file(params, key, options) or
208
- default_uploaded_file(params, key, options)
206
+ upload_cache = (
207
+ current_upload_cache_for(params_map, key, options) or
208
+ previous_upload_cache_for(params_map, key, options) or
209
+ default_upload_cache_for(params_map, key, options)
209
210
  )
211
+
212
+ value = params_map.get(key)
213
+
214
+ update_params(params, key, value)
215
+
216
+ upload_cache
217
+ end
218
+ alias_method('for', 'cache')
219
+
220
+ def update_params(params, key, value)
221
+ key = Array(key).flatten
222
+
223
+ leaf = key.pop
224
+ path = key
225
+ node = params
226
+
227
+ until path.empty?
228
+ key = path.shift
229
+ case node
230
+ when Array
231
+ index = Integer(key)
232
+ break unless node[index]
233
+ node = node[index]
234
+ else
235
+ break unless node.has_key?(key)
236
+ node = node[key]
237
+ end
238
+ end
239
+
240
+ node[leaf] = value
210
241
  end
211
242
 
212
- def currently_uploaded_file(params, key, options)
243
+ def current_upload_cache_for(params, key, options)
213
244
  upload = params.get(key)
245
+ if upload.respond_to?(:upload_cache) and upload.upload_cache
246
+ return upload.upload_cache
247
+ end
214
248
 
215
249
  if upload.respond_to?(:read)
216
250
  tmpdir do |tmp|
217
251
  original_basename =
218
252
  [:original_path, :original_filename, :path, :filename].
219
- map{|msg| upload.send(msg) if upload.respond_to?(msg)}.compact.first
253
+ map{|msg| upload.send(msg) if upload.respond_to?(msg)}.compact.first
254
+
220
255
  basename = cleanname(original_basename)
221
256
 
222
257
  path = File.join(tmp, basename)
223
- open(path, 'wb'){|fd| fd.write(upload.read)}
258
+
259
+ copied = false
260
+
261
+ rewind(upload) do
262
+ src = upload.path
263
+ dst = path
264
+
265
+ strategies = [
266
+ proc{ `ln -f #{ src.inspect } #{ dst.inspect } || cp -f #{ src.inspect } #{ dst.inspect }`},
267
+ proc{ FileUtils.ln(src, dst) },
268
+ proc{ FileUtils.cp(src, dst) },
269
+ proc{
270
+ open(dst, 'wb'){|fd| fd.write(upload.read)}
271
+ }
272
+ ]
273
+
274
+ FileUtils.rm_f(dst)
275
+
276
+ strategies.each do |strategy|
277
+ strategy.call rescue nil
278
+ break if((copied = test(?e, dst)))
279
+ end
280
+ end
281
+
282
+ raise("failed to copy #{ upload.path.inspect } -> #{ path.inspect }") unless copied
283
+
224
284
  upload_cache = UploadCache.new(key, path, options)
225
285
  params.set(key, upload_cache.io)
226
286
  return upload_cache
227
287
  end
228
288
  end
229
289
 
230
- false
290
+ nil
231
291
  end
232
292
 
233
- def previously_uploaded_file(params, key, options)
234
- cache_key = cache_key_for(key)
235
- upload_cache = params.get(cache_key)
293
+ def previous_upload_cache_for(params, key, options)
294
+ upload = params.get(key)
295
+ if upload.respond_to?(:upload_cache) and upload.upload_cache
296
+ return upload.upload_cache
297
+ end
236
298
 
237
- if upload_cache
238
- dirname, basename = File.split(File.expand_path(upload_cache))
299
+ upload = params.get(cache_key_for(key))
300
+
301
+ if upload
302
+ dirname, basename = File.split(File.expand_path(upload))
239
303
  relative_dirname = File.basename(dirname)
240
304
  relative_basename = File.join(relative_dirname, basename)
241
305
  path = root + '/' + relative_basename
306
+
242
307
  upload_cache = UploadCache.new(key, path, options)
243
308
  params.set(key, upload_cache.io)
244
309
  return upload_cache
245
310
  end
246
311
 
247
- false
312
+ nil
248
313
  end
249
314
 
250
- def default_uploaded_file(params, key, options)
315
+ def default_upload_cache_for(params, key, options)
251
316
  upload_cache = UploadCache.new(key, options)
252
- params.set(key, upload_cache.io) if upload_cache.io
317
+ params.set(key, upload_cache.io)
253
318
  return upload_cache
254
319
  end
320
+
321
+ def rewind(io, &block)
322
+ begin
323
+ pos = io.pos
324
+ io.flush
325
+ io.rewind
326
+ rescue
327
+ nil
328
+ end
329
+
330
+ begin
331
+ block.call
332
+ ensure
333
+ begin
334
+ io.pos = pos
335
+ rescue
336
+ nil
337
+ end
338
+ end
339
+ end
255
340
  end
256
341
 
257
342
  attr_accessor :key
258
343
  attr_accessor :cache_key
344
+ attr_accessor :options
259
345
  attr_accessor :name
260
346
  attr_accessor :path
261
347
  attr_accessor :dirname
@@ -268,18 +354,18 @@ class UploadCache
268
354
  IOs = {}
269
355
 
270
356
  def initialize(key, *args)
271
- options = Map.options_for!(args)
357
+ @options = Map.options_for!(args)
272
358
 
273
359
  @key = key
274
360
  @cache_key = UploadCache.cache_key_for(@key)
275
361
  @name = UploadCache.name_for(@cache_key)
276
362
 
277
- path = args.shift || options[:path]
363
+ path = args.shift || @options[:path]
278
364
 
279
- default = Map.for(options[:default])
365
+ default = Map.for(@options[:default])
280
366
 
281
- @default_url = default[:url] || options[:default_url] || UploadCache.default.url
282
- @default_path = default[:path] || options[:default_path] || UploadCache.default.path
367
+ @default_url = default[:url] || @options[:default_url] || UploadCache.default.url
368
+ @default_path = default[:path] || @options[:default_path] || UploadCache.default.path
283
369
 
284
370
  if path
285
371
  @path = path
@@ -294,14 +380,46 @@ class UploadCache
294
380
  @io = open(@path || @default_path, 'rb')
295
381
  IOs[object_id] = @io.fileno
296
382
  ObjectSpace.define_finalizer(self, UploadCache.method(:finalizer).to_proc)
383
+ @io.send(:extend, WeakReference)
384
+ @io.upload_cache = self
385
+ end
386
+ end
387
+
388
+ module WeakReference
389
+ attr_accessor :upload_cache_object_id
390
+
391
+ def upload_cache
392
+ begin
393
+ ObjectSpace._id2ref(upload_cache_object_id)
394
+ rescue Object
395
+ nil
396
+ end
397
+ end
398
+
399
+ def upload_cache=(upload_cache)
400
+ self.upload_cache_object_id = upload_cache.object_id
297
401
  end
298
402
  end
299
403
 
404
+ def inspect
405
+ {
406
+ UploadCache.name =>
407
+ {
408
+ :key => key, :cache_key => key, :name => name, :path => path, :io => io
409
+ }
410
+ }.inspect
411
+ end
412
+
413
+ def blank?
414
+ @path.blank?
415
+ end
416
+
300
417
  def url
301
418
  if @value
302
419
  File.join(UploadCache.url, @value)
303
420
  else
304
421
  @default_url ? @default_url : nil
422
+ #defined?(@placeholder) ? @placeholder : nil
305
423
  end
306
424
  end
307
425
 
@@ -330,19 +448,24 @@ class UploadCache
330
448
  string.html_safe
331
449
  end
332
450
 
333
- def clear!
334
- return if UploadCache.turd?
451
+ def clear!(&block)
452
+ result = block ? block.call(@path) : nil
335
453
 
336
- begin
337
- FileUtils.rm_rf(@dirname) if test(?d, @dirname)
338
- rescue
339
- nil
340
- ensure
341
- @io.close rescue nil
342
- IOs.delete(object_id)
343
- Thread.new{ UploadCache.clear! }
454
+ unless UploadCache.turd?
455
+ begin
456
+ FileUtils.rm_rf(@dirname) if test(?d, @dirname)
457
+ rescue
458
+ nil
459
+ ensure
460
+ @io.close rescue nil
461
+ IOs.delete(object_id)
462
+ Thread.new{ UploadCache.clear! }
463
+ end
344
464
  end
465
+
466
+ result
345
467
  end
468
+ alias_method('clear', 'clear!')
346
469
  end
347
470
 
348
471
  Upload_cache = UploadCache unless defined?(Upload_cache)
@@ -0,0 +1,200 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # simple testing support
3
+ #
4
+ # -*- encoding : utf-8 -*-
5
+ #
6
+ require 'test/unit'
7
+
8
+ testdir = File.expand_path(File.dirname(__FILE__))
9
+ rootdir = File.dirname(testdir)
10
+ libdir = File.join(rootdir, 'lib')
11
+
12
+ STDOUT.sync = true
13
+
14
+ $:.unshift(testdir) unless $:.include?(testdir)
15
+ $:.unshift(libdir) unless $:.include?(libdir)
16
+ $:.unshift(rootdir) unless $:.include?(rootdir)
17
+
18
+ class Testing
19
+ class Slug < ::String
20
+ def Slug.for(*args)
21
+ string = args.flatten.compact.join('-')
22
+ words = string.to_s.scan(%r/\w+/)
23
+ words.map!{|word| word.gsub %r/[^0-9a-zA-Z_-]/, ''}
24
+ words.delete_if{|word| word.nil? or word.strip.empty?}
25
+ new(words.join('-').downcase)
26
+ end
27
+ end
28
+
29
+ class Context
30
+ attr_accessor :name
31
+
32
+ def initialize(name, *args)
33
+ @name = name
34
+ end
35
+
36
+ def to_s
37
+ Slug.for(name)
38
+ end
39
+ end
40
+ end
41
+
42
+ def Testing(*args, &block)
43
+ Class.new(::Test::Unit::TestCase) do
44
+
45
+ ## class methods
46
+ #
47
+ class << self
48
+ def contexts
49
+ @contexts ||= []
50
+ end
51
+
52
+ def context(*args, &block)
53
+ return contexts.last if(args.empty? and block.nil?)
54
+
55
+ context = Testing::Context.new(*args)
56
+ contexts.push(context)
57
+
58
+ begin
59
+ block.call(context)
60
+ ensure
61
+ contexts.pop
62
+ end
63
+ end
64
+
65
+ def slug_for(*args)
66
+ string = [context, args].flatten.compact.join('-')
67
+ words = string.to_s.scan(%r/\w+/)
68
+ words.map!{|word| word.gsub %r/[^0-9a-zA-Z_-]/, ''}
69
+ words.delete_if{|word| word.nil? or word.strip.empty?}
70
+ words.join('-').downcase.sub(/_$/, '')
71
+ end
72
+
73
+ def name() const_get(:Name) end
74
+
75
+ def testno()
76
+ '%05d' % (@testno ||= 0)
77
+ ensure
78
+ @testno += 1
79
+ end
80
+
81
+ def testing(*args, &block)
82
+ method = ["test", testno, slug_for(*args)].delete_if{|part| part.empty?}.join('_')
83
+ define_method(method, &block)
84
+ end
85
+
86
+ def test(*args, &block)
87
+ testing(*args, &block)
88
+ end
89
+
90
+ def setup(&block)
91
+ define_method(:setup, &block) if block
92
+ end
93
+
94
+ def teardown(&block)
95
+ define_method(:teardown, &block) if block
96
+ end
97
+
98
+ def prepare(&block)
99
+ @prepare ||= []
100
+ @prepare.push(block) if block
101
+ @prepare
102
+ end
103
+
104
+ def cleanup(&block)
105
+ @cleanup ||= []
106
+ @cleanup.push(block) if block
107
+ @cleanup
108
+ end
109
+ end
110
+
111
+ ## configure the subclass!
112
+ #
113
+ const_set(:Testno, '0')
114
+ slug = slug_for(*args).gsub(%r/-/,'_')
115
+ name = ['TESTING', '%03d' % const_get(:Testno), slug].delete_if{|part| part.empty?}.join('_')
116
+ name = name.upcase!
117
+ const_set(:Name, name)
118
+ const_set(:Missing, Object.new.freeze)
119
+
120
+ ## instance methods
121
+ #
122
+ alias_method('__assert__', 'assert')
123
+
124
+ def assert(*args, &block)
125
+ if args.size == 1 and args.first.is_a?(Hash)
126
+ options = args.first
127
+ expected = getopt(:expected, options){ missing }
128
+ actual = getopt(:actual, options){ missing }
129
+ if expected == missing and actual == missing
130
+ actual, expected, *ignored = options.to_a.flatten
131
+ end
132
+ expected = expected.call() if expected.respond_to?(:call)
133
+ actual = actual.call() if actual.respond_to?(:call)
134
+ assert_equal(expected, actual)
135
+ end
136
+
137
+ if block
138
+ label = "assert(#{ args.join(' ') })"
139
+ result = nil
140
+ assert_nothing_raised{ result = block.call }
141
+ __assert__(result, label)
142
+ result
143
+ else
144
+ result = args.shift
145
+ label = "assert(#{ args.join(' ') })"
146
+ __assert__(result, label)
147
+ result
148
+ end
149
+ end
150
+
151
+ def missing
152
+ self.class.const_get(:Missing)
153
+ end
154
+
155
+ def getopt(opt, hash, options = nil, &block)
156
+ [opt.to_s, opt.to_s.to_sym].each do |key|
157
+ return hash[key] if hash.has_key?(key)
158
+ end
159
+ default =
160
+ if block
161
+ block.call
162
+ else
163
+ options.is_a?(Hash) ? options[:default] : nil
164
+ end
165
+ return default
166
+ end
167
+
168
+ def subclass_of exception
169
+ class << exception
170
+ def ==(other) super or self > other end
171
+ end
172
+ exception
173
+ end
174
+
175
+ ##
176
+ #
177
+ module_eval(&block)
178
+
179
+ self.setup()
180
+ self.prepare.each{|b| b.call()}
181
+
182
+ at_exit{
183
+ self.teardown()
184
+ self.cleanup.each{|b| b.call()}
185
+ }
186
+
187
+ self
188
+ end
189
+ end
190
+
191
+
192
+ if $0 == __FILE__
193
+
194
+ Testing 'Testing' do
195
+ testing('foo'){ assert true }
196
+ test{ assert true }
197
+ p instance_methods.grep(/test/)
198
+ end
199
+
200
+ end
@@ -0,0 +1,173 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'fileutils'
3
+ require 'testing'
4
+ require 'upload_cache'
5
+
6
+ Testing UploadCache do
7
+
8
+ ##
9
+ #
10
+ testing 'upload_cache will cache an upload and alter params to point to it' do
11
+ uploaded_file = new_uploaded_file
12
+
13
+ params = {
14
+ :key => uploaded_file
15
+ }
16
+
17
+ upload_cache = assert{ UploadCache.cache(params, :key) }
18
+
19
+ assert{ params[:key] }
20
+ assert{ params[:key].respond_to?(:upload_cache_object_id) }
21
+ assert{ params[:key].respond_to?(:upload_cache) }
22
+
23
+
24
+ assert{ upload_cache.io }
25
+ assert{ upload_cache.path }
26
+ assert{ IO.read(uploaded_file.path) == IO.read(upload_cache.io.path) }
27
+ end
28
+
29
+ ##
30
+ #
31
+ testing 'upload_cache looks for previously uploaded files under a special key' do
32
+ uploaded_file_path = previously_uploaded_file_path
33
+
34
+ params = {
35
+ :key => nil,
36
+ :key_upload_cache => uploaded_file_path
37
+ }
38
+
39
+ upload_cache = assert{ UploadCache.cache(params, :key) }
40
+
41
+ assert{ params[:key] }
42
+ assert{ params[:key].respond_to?(:upload_cache_object_id) }
43
+ assert{ params[:key].respond_to?(:upload_cache) }
44
+
45
+
46
+ assert{ upload_cache.io }
47
+ assert{ upload_cache.path }
48
+ assert{ IO.read(File.join(Public, uploaded_file_path)) == IO.read(upload_cache.io.path) }
49
+ end
50
+
51
+ ##
52
+ #
53
+ testing 'upload_cache will return the same object iff nothing has changed' do
54
+ params = {
55
+ :key => new_uploaded_file
56
+ }
57
+
58
+ a = assert{ UploadCache.cache(params, :key) }
59
+ b = assert{ UploadCache.cache(params, :key) }
60
+ assert{ a.object_id == b.object_id }
61
+ end
62
+
63
+ ##
64
+ #
65
+ testing 'upload_cache will *not* return the same object iff something has changed' do
66
+ params = {
67
+ :key => new_uploaded_file
68
+ }
69
+
70
+ a = assert{ UploadCache.cache(params, :key) }
71
+ b = assert{ UploadCache.cache(params, :key) }
72
+ assert{ a.object_id == b.object_id }
73
+
74
+ params[:key] = new_uploaded_file
75
+ c = assert{ UploadCache.cache(params, :key) }
76
+ assert{ a.object_id != c.object_id }
77
+ assert{ b.object_id != c.object_id }
78
+ end
79
+
80
+ ##
81
+ #
82
+ testing 'upload_cache works on file handles that need flushing' do
83
+ uploaded_file = new_uploaded_file
84
+
85
+ params = {
86
+ :key => uploaded_file
87
+ }
88
+
89
+ uploaded_file.rewind
90
+ uploaded_file.sync = false
91
+ uploaded_file.write('a half baked write')
92
+
93
+ upload_cache = assert{ UploadCache.cache(params, :key) }
94
+
95
+ assert{ params[:key] }
96
+ assert{ params[:key].respond_to?(:upload_cache_object_id) }
97
+ assert{ params[:key].respond_to?(:upload_cache) }
98
+
99
+ assert{ upload_cache.io }
100
+ assert{ upload_cache.path }
101
+ assert{ IO.read(uploaded_file.path) == IO.read(upload_cache.io.path) }
102
+ end
103
+
104
+
105
+ TestDir = File.expand_path(File.dirname(__FILE__))
106
+ TestTmpDir = File.join(TestDir, 'tmp')
107
+ Public = File.join(TestTmpDir, 'public')
108
+ PublicSystem = File.join(TestTmpDir, 'public/system')
109
+ PublicSystemUploadCache = File.join(TestTmpDir, 'public/system/upload_cache')
110
+ PublicSystemUploads = File.join(TestTmpDir, 'public/system/uploads')
111
+
112
+ FileUtils.mkdir_p(TestTmpDir)
113
+ FileUtils.mkdir_p(Public)
114
+ FileUtils.mkdir_p(PublicSystem)
115
+ FileUtils.mkdir_p(PublicSystemUploadCache)
116
+ FileUtils.mkdir_p(PublicSystemUploads)
117
+
118
+ setup do
119
+ assert{ UploadCache.root = PublicSystemUploadCache }
120
+ end
121
+
122
+ at_exit do
123
+ glob = File.join(TestTmpDir, '**/**')
124
+ Dir.glob(glob) do |entry|
125
+ #FileUtils.rm_rf(entry)
126
+ end
127
+ end
128
+
129
+ Count = '0'
130
+ def new_uploaded_file(&block)
131
+ path = File.join(PublicSystemUploads, Count)
132
+ at_exit{ FileUtils.rm_f(path) }
133
+ fd = open(path, 'w+')
134
+ fd.puts(Count)
135
+ #fd.flush
136
+ #fd.rewind
137
+ return fd unless block
138
+ begin
139
+ block.call(fd)
140
+ ensure
141
+ fd.close rescue nil
142
+ end
143
+ ensure
144
+ Count.succ!
145
+ end
146
+
147
+ def previously_uploaded_file_path
148
+ new_uploaded_file do |uploaded_file|
149
+ basename = File.basename(uploaded_file.path)
150
+ uuid = assert{ UploadCache.uuid }
151
+ dst = File.join(PublicSystemUploadCache, uuid, basename)
152
+ FileUtils.mkdir(File.dirname(dst))
153
+ open(dst, 'w') do |fd|
154
+ fd.write(uploaded_file.read)
155
+ end
156
+ "/system/upload_cache/#{ uuid }/#{ basename }"
157
+ end
158
+ end
159
+ end
160
+
161
+
162
+
163
+
164
+
165
+
166
+ BEGIN {
167
+ testdir = File.dirname(File.expand_path(__FILE__))
168
+ testlibdir = File.join(testdir, 'lib')
169
+ rootdir = File.dirname(testdir)
170
+ libdir = File.join(rootdir, 'lib')
171
+ $LOAD_PATH.push(libdir)
172
+ $LOAD_PATH.push(testlibdir)
173
+ }
@@ -3,13 +3,21 @@
3
3
 
4
4
  Gem::Specification::new do |spec|
5
5
  spec.name = "upload_cache"
6
- spec.version = "1.4.1"
6
+ spec.version = "2.2.0"
7
7
  spec.platform = Gem::Platform::RUBY
8
8
  spec.summary = "upload_cache"
9
9
  spec.description = "description: upload_cache kicks the ass"
10
10
 
11
11
  spec.files =
12
- ["README", "Rakefile", "lib", "lib/upload_cache.rb", "upload_cache.gemspec"]
12
+ ["README",
13
+ "Rakefile",
14
+ "lib",
15
+ "lib/upload_cache.rb",
16
+ "test",
17
+ "test/lib",
18
+ "test/lib/testing.rb",
19
+ "test/upload_cache_test.rb",
20
+ "upload_cache.gemspec"]
13
21
 
14
22
  spec.executables = []
15
23
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: upload_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 2.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-06 00:00:00.000000000 Z
12
+ date: 2012-02-18 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: ! 'description: upload_cache kicks the ass'
15
15
  email: ara.t.howard@gmail.com
@@ -20,6 +20,8 @@ files:
20
20
  - README
21
21
  - Rakefile
22
22
  - lib/upload_cache.rb
23
+ - test/lib/testing.rb
24
+ - test/upload_cache_test.rb
23
25
  - upload_cache.gemspec
24
26
  homepage: https://github.com/ahoward/upload_cache
25
27
  licenses: []