asset_cloud 2.7.0 → 2.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +42 -0
  3. data/.github/workflows/cla.yml +22 -0
  4. data/.rubocop.yml +3 -1
  5. data/Gemfile +5 -3
  6. data/History.md +8 -0
  7. data/README.rdoc +3 -4
  8. data/Rakefile +18 -16
  9. data/asset_cloud.gemspec +19 -18
  10. data/dev.yml +1 -1
  11. data/lib/asset_cloud/asset.rb +17 -13
  12. data/lib/asset_cloud/asset_extension.rb +27 -15
  13. data/lib/asset_cloud/base.rb +77 -72
  14. data/lib/asset_cloud/bucket.rb +5 -2
  15. data/lib/asset_cloud/buckets/active_record_bucket.rb +16 -14
  16. data/lib/asset_cloud/buckets/blackhole_bucket.rb +2 -0
  17. data/lib/asset_cloud/buckets/bucket_chain.rb +38 -31
  18. data/lib/asset_cloud/buckets/file_system_bucket.rb +14 -15
  19. data/lib/asset_cloud/buckets/gcs_bucket.rb +6 -8
  20. data/lib/asset_cloud/buckets/invalid_bucket.rb +9 -6
  21. data/lib/asset_cloud/buckets/memory_bucket.rb +7 -4
  22. data/lib/asset_cloud/buckets/s3_bucket.rb +11 -8
  23. data/lib/asset_cloud/buckets/versioned_memory_bucket.rb +4 -2
  24. data/lib/asset_cloud/callbacks.rb +9 -5
  25. data/lib/asset_cloud/free_key_locator.rb +6 -6
  26. data/lib/asset_cloud/metadata.rb +11 -7
  27. data/lib/asset_cloud/validations.rb +9 -5
  28. data/lib/asset_cloud.rb +23 -21
  29. data/spec/active_record_bucket_spec.rb +27 -26
  30. data/spec/asset_cloud/metadata_spec.rb +4 -2
  31. data/spec/asset_extension_spec.rb +17 -16
  32. data/spec/asset_spec.rb +27 -21
  33. data/spec/base_spec.rb +93 -92
  34. data/spec/blackhole_bucket_spec.rb +12 -11
  35. data/spec/bucket_chain_spec.rb +61 -56
  36. data/spec/bucket_spec.rb +6 -5
  37. data/spec/callbacks_spec.rb +52 -32
  38. data/spec/file_system_spec.rb +25 -24
  39. data/spec/find_free_key_spec.rb +16 -17
  40. data/spec/gcs_bucket_remote_spec.rb +23 -22
  41. data/spec/gcs_bucket_spec.rb +48 -60
  42. data/spec/memory_bucket_spec.rb +12 -11
  43. data/spec/mock_s3_interface.rb +17 -6
  44. data/spec/remote_s3_bucket_spec.rb +31 -28
  45. data/spec/s3_bucket_spec.rb +19 -17
  46. data/spec/spec_helper.rb +8 -7
  47. data/spec/validations_spec.rb +13 -12
  48. data/spec/versioned_memory_bucket_spec.rb +11 -10
  49. metadata +10 -33
  50. data/.github/probots.yml +0 -2
  51. data/.rubocop_todo.yml +0 -326
  52. data/.travis.yml +0 -12
@@ -1,42 +1,44 @@
1
- require 'uri/rfc2396_parser'
1
+ # frozen_string_literal: true
2
2
 
3
- module AssetCloud
3
+ require "uri/rfc2396_parser"
4
4
 
5
+ module AssetCloud
5
6
  class IllegalPath < StandardError
6
7
  end
7
8
 
8
9
  class Base
9
10
  cattr_accessor :logger
10
11
 
11
- VALID_PATHS = /\A
12
+ VALID_PATHS = %r{\A
12
13
  (
13
- (\w) #Filename can be a single letter or underscore
14
- | #OR it is many and follows the below rules
14
+ (\w) # Filename can be a single letter or underscore
15
+ | # OR it is many and follows the below rules
15
16
  (
16
- (\.?[\w\[\]\(\)\-\@]) #It can start with a dot but it must have a following character
17
+ (\.?[\w\[\]\(\)\-\@]) # It can start with a dot but it must have a following character
17
18
  (
18
- [\w\[\]\(\)\-\@] #You can have a letter without any following conditions
19
+ [\w\[\]\(\)\-\@] # You can have a letter without any following conditions
19
20
  |
20
- [\ ][\w\[\]\(\)\-\@\.] #If there is a space you need to have a normal letter afterward or a dot
21
+ [\ ][\w\[\]\(\)\-\@\.] # If there is a space you need to have a normal letter afterward or a dot
21
22
  |
22
- [\/][\w\[\]\(\)\-\@] #If there is a slash you need to have a normal letter afterward
23
+ [/][\w\[\]\(\)\-\@] # If there is a slash you need to have a normal letter afterward
23
24
  |
24
- [\/][\.][\w\[\]\(\)\-\@] #Though a slash could be followed by a dot so long as there is a normal letter afterward
25
+ [/][\.][\w\[\]\(\)\-\@] # Though a slash could be followed by a dot
26
+ # so long as there is a normal letter afterward
25
27
  |
26
- [\.]+[\w\[\]\(\)\-\@]+ #One or more dots must be followed by one (or more) normal letters
27
- )* #Zero to many of these combinations.
28
+ [\.]+[\w\[\]\(\)\-\@]+ # One or more dots must be followed by one (or more) normal letters
29
+ )* # Zero to many of these combinations.
28
30
  )
29
- )\z/x
30
- MATCH_BUCKET = /^(\w+)(\/|$)/
31
+ )\z}x
32
+ MATCH_BUCKET = %r{^(\w+)(/|$)}
31
33
 
32
34
  URI_PARSER = URI::RFC2396_Parser.new
33
35
 
34
36
  attr_accessor :url, :root
35
37
 
36
38
  class_attribute :root_bucket_class
37
- self.root_bucket_class = 'AssetCloud::FileSystemBucket'.freeze
39
+ self.root_bucket_class = "AssetCloud::FileSystemBucket"
38
40
  class_attribute :root_asset_class
39
- self.root_asset_class = 'AssetCloud::Asset'.freeze
41
+ self.root_asset_class = "AssetCloud::Asset"
40
42
 
41
43
  class_attribute :bucket_classes
42
44
  self.bucket_classes = {}.freeze
@@ -45,56 +47,68 @@ module AssetCloud
45
47
  class_attribute :asset_extension_classes
46
48
  self.asset_extension_classes = {}.freeze
47
49
 
48
- def self.bucket(*args)
49
- asset_class = if args.last.is_a? Hash
50
- convert_to_class_name_if_possible(args.pop[:asset_class])
51
- end
50
+ class << self
51
+ def bucket(*args)
52
+ asset_class = if args.last.is_a?(Hash)
53
+ convert_to_class_name_if_possible(args.pop[:asset_class])
54
+ end
52
55
 
53
- bucket_class = if args.last.is_a? Class
54
- convert_to_class_name_if_possible(args.pop)
55
- else
56
- raise ArgumentError, 'requires a bucket class'
57
- end
56
+ bucket_class = if args.last.is_a?(Class)
57
+ convert_to_class_name_if_possible(args.pop)
58
+ else
59
+ raise ArgumentError, "requires a bucket class"
60
+ end
58
61
 
59
- if bucket_name = args.first
60
- self.bucket_classes = bucket_classes.merge(bucket_name.to_sym => bucket_class).freeze
61
- self.asset_classes = asset_classes.merge(bucket_name.to_sym => asset_class).freeze if asset_class
62
- else
63
- self.root_bucket_class = bucket_class
64
- if asset_class
65
- raise ArgumentError, 'asset_class on the root bucket cannot be a proc' if asset_class.is_a?(Proc)
66
- self.root_asset_class = asset_class
62
+ if (bucket_name = args.first)
63
+ self.bucket_classes = bucket_classes.merge(bucket_name.to_sym => bucket_class).freeze
64
+ self.asset_classes = asset_classes.merge(bucket_name.to_sym => asset_class).freeze if asset_class
65
+ else
66
+ self.root_bucket_class = bucket_class
67
+ if asset_class
68
+ raise ArgumentError, "asset_class on the root bucket cannot be a proc" if asset_class.is_a?(Proc)
69
+
70
+ self.root_asset_class = asset_class
71
+ end
67
72
  end
68
73
  end
69
- end
70
74
 
71
- def self.asset_extensions(*args)
72
- opts = args.last.is_a?(Hash) ? args.pop.slice(:only, :except) : {}
73
- opts.each do |k,v|
74
- opts[k] = [v].flatten.map(&:to_sym)
75
+ def asset_extensions(*args)
76
+ opts = args.last.is_a?(Hash) ? args.pop.slice(:only, :except) : {}
77
+ opts.each do |k, v|
78
+ opts[k] = [v].flatten.map(&:to_sym)
79
+ end
80
+
81
+ args.each do |klass|
82
+ klass = convert_to_class_name_if_possible(klass)
83
+ self.asset_extension_classes = asset_extension_classes.merge(klass => opts).freeze
84
+ end
75
85
  end
76
86
 
77
- args.each do |klass|
78
- klass = convert_to_class_name_if_possible(klass)
79
- self.asset_extension_classes = asset_extension_classes.merge(klass => opts).freeze
87
+ private
88
+
89
+ def convert_to_class_name_if_possible(klass)
90
+ if klass.is_a?(Class) && klass.name.present?
91
+ klass.name
92
+ else
93
+ klass
94
+ end
80
95
  end
81
96
  end
82
97
 
83
98
  def buckets
84
99
  @buckets ||= Hash.new do |hash, key|
85
- if klass = self.class.bucket_classes[key]
86
- hash[key] = constantize_if_necessary(klass).new(self, key)
87
- else
88
- hash[key] = nil
100
+ hash[key] = if (klass = self.class.bucket_classes[key])
101
+ constantize_if_necessary(klass).new(self, key)
89
102
  end
90
103
  end
91
104
  end
92
105
 
93
- def initialize(root, url = '/')
94
- @root, @url = root, url
106
+ def initialize(root, url = "/")
107
+ @root = root
108
+ @url = url
95
109
  end
96
110
 
97
- def url_for(key, options={})
111
+ def url_for(key, options = {})
98
112
  File.join(@url, URI_PARSER.escape(key))
99
113
  end
100
114
 
@@ -140,13 +154,13 @@ module AssetCloud
140
154
  end
141
155
 
142
156
  def build(key, value = nil, &block)
143
- logger.info { " [#{self.class.name}] Building asset #{key}" } if logger
157
+ logger&.info { " [#{self.class.name}] Building asset #{key}" }
144
158
  asset_class_for(key).new(self, key, value, Metadata.non_existing, &block)
145
159
  end
146
160
 
147
161
  def write(key, value)
148
162
  check_key_for_errors(key)
149
- logger.info { " [#{self.class.name}] Writing #{value.size} bytes to #{key}" } if logger
163
+ logger&.info { " [#{self.class.name}] Writing #{value.size} bytes to #{key}" }
150
164
 
151
165
  bucket_for(key).write(key, value)
152
166
  end
@@ -158,25 +172,25 @@ module AssetCloud
158
172
  end
159
173
 
160
174
  def read(key)
161
- logger.info { " [#{self.class.name}] Reading from #{key}" } if logger
175
+ logger&.info { " [#{self.class.name}] Reading from #{key}" }
162
176
 
163
177
  bucket_for(key).read(key)
164
178
  end
165
179
 
166
180
  def stat(key)
167
- logger.info { " [#{self.class.name}] Statting #{key}" } if logger
181
+ logger&.info { " [#{self.class.name}] Statting #{key}" }
168
182
 
169
183
  bucket_for(key).stat(key)
170
184
  end
171
185
 
172
186
  def ls(key)
173
- logger.info { " [#{self.class.name}] Listing objects in #{key}" } if logger
187
+ logger&.info { " [#{self.class.name}] Listing objects in #{key}" }
174
188
 
175
189
  bucket_for(key).ls(key)
176
190
  end
177
191
 
178
192
  def exist?(key)
179
- if fp = stat(key)
193
+ if (fp = stat(key))
180
194
  fp.exist?
181
195
  else
182
196
  false
@@ -188,7 +202,7 @@ module AssetCloud
188
202
  end
189
203
 
190
204
  def delete(key)
191
- logger.info { " [#{self.class.name}] Deleting #{key}" } if logger
205
+ logger&.info { " [#{self.class.name}] Deleting #{key}" }
192
206
 
193
207
  bucket_for(key).delete(key)
194
208
  end
@@ -211,17 +225,17 @@ module AssetCloud
211
225
  # versioning
212
226
 
213
227
  def read_version(key, version)
214
- logger.info { " [#{self.class.name}] Reading from #{key} at version #{version}" } if logger
228
+ logger&.info { " [#{self.class.name}] Reading from #{key} at version #{version}" }
215
229
  bucket_for(key).read_version(key, version)
216
230
  end
217
231
 
218
232
  def versions(key)
219
- logger.info { " [#{self.class.name}] Getting all versions for #{key}" } if logger
233
+ logger&.info { " [#{self.class.name}] Getting all versions for #{key}" }
220
234
  bucket_for(key).versions(key)
221
235
  end
222
236
 
223
237
  def version_details(key)
224
- logger.info { " [#{self.class.name}] Getting all version details for #{key}" } if logger
238
+ logger&.info { " [#{self.class.name}] Getting all version details for #{key}" }
225
239
  bucket_for(key).version_details(key)
226
240
  end
227
241
 
@@ -239,40 +253,31 @@ module AssetCloud
239
253
  klasses = extensions.keys.select do |ext|
240
254
  opts = extensions[ext]
241
255
  (opts.key?(:only) ? opts[:only].include?(bucket) : true) &&
242
- (opts.key?(:except) ? !opts[:except].include?(bucket) : true)
256
+ (opts.key?(:except) ? !opts[:except].include?(bucket) : true)
243
257
  end
244
- klasses.map {|klass| constantize_if_necessary(klass)}
258
+ klasses.map { |klass| constantize_if_necessary(klass) }
245
259
  end
246
260
 
247
261
  protected
248
262
 
249
263
  def bucket_symbol_for_key(key)
250
- $1.to_sym if key =~ MATCH_BUCKET
264
+ Regexp.last_match(1).to_sym if key =~ MATCH_BUCKET
251
265
  end
252
266
 
253
267
  def root_bucket
254
- @default_bucket ||= constantize_if_necessary(self.class.root_bucket_class).new(self, '')
268
+ @default_bucket ||= constantize_if_necessary(self.class.root_bucket_class).new(self, "")
255
269
  end
256
270
 
257
271
  def constantize_if_necessary(klass)
258
272
  klass.is_a?(Class) ? klass : klass.constantize
259
273
  end
260
274
 
261
- def self.convert_to_class_name_if_possible(klass)
262
- if klass.is_a?(Class) && klass.name.present?
263
- klass.name
264
- else
265
- klass
266
- end
267
- end
268
-
269
275
  def check_key_for_errors(key)
270
276
  raise IllegalPath, "key cannot be empty" if key.blank?
271
277
  raise IllegalPath, "#{key.inspect} contains illegal characters" unless supports?(key)
272
278
  rescue => e
273
- logger.info { " [#{self.class.name}] bad key #{e.message}" } if logger
279
+ logger&.info { " [#{self.class.name}] bad key #{e.message}" }
274
280
  raise
275
281
  end
276
-
277
282
  end
278
283
  end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AssetCloud
2
4
  class AssetNotFoundError < StandardError
3
- def initialize(key, version=nil)
5
+ def initialize(key, version = nil)
4
6
  super(version ? "Could not find version #{version} of asset #{key}" : "Could not find asset #{key}")
5
7
  end
6
8
  end
@@ -10,7 +12,8 @@ module AssetCloud
10
12
  attr_accessor :cloud
11
13
 
12
14
  def initialize(cloud, name)
13
- @cloud, @name = cloud, name
15
+ @cloud = cloud
16
+ @name = name
14
17
  end
15
18
 
16
19
  def ls(key = nil)
@@ -1,35 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AssetCloud
2
4
  class ActiveRecordBucket < AssetCloud::Bucket
3
5
  class_attribute :key_attribute, :value_attribute
4
- self.key_attribute = 'key'
5
- self.value_attribute = 'value'
6
+ self.key_attribute = "key"
7
+ self.value_attribute = "value"
6
8
 
7
- def ls(key=name)
8
- col = records.connection.quote_column_name(self.key_attribute)
9
- records.all(:conditions => ["#{col} LIKE ?", "#{key}%"]).map do |r|
10
- cloud[r.send(self.key_attribute)]
9
+ def ls(key = name)
10
+ col = records.connection.quote_column_name(key_attribute)
11
+ records.all(conditions: ["#{col} LIKE ?", "#{key}%"]).map do |r|
12
+ cloud[r.send(key_attribute)]
11
13
  end
12
14
  end
13
15
 
14
16
  def read(key)
15
- find_record!(key).send(self.value_attribute)
17
+ find_record!(key).send(value_attribute)
16
18
  end
17
19
 
18
20
  def write(key, value)
19
- record = records.send("find_or_initialize_by_#{self.key_attribute}", key.to_s)
20
- record.send("#{self.value_attribute}=", value)
21
+ record = records.send("find_or_initialize_by_#{key_attribute}", key.to_s)
22
+ record.send("#{value_attribute}=", value)
21
23
  record.save!
22
24
  end
23
25
 
24
26
  def delete(key)
25
- if record = find_record(key)
27
+ if (record = find_record(key))
26
28
  record.destroy
27
29
  end
28
30
  end
29
31
 
30
32
  def stat(key)
31
- if record = find_record(key)
32
- AssetCloud::Metadata.new(true, record.send(self.value_attribute).size, record.created_at, record.updated_at)
33
+ if (record = find_record(key))
34
+ AssetCloud::Metadata.new(true, record.send(value_attribute).size, record.created_at, record.updated_at)
33
35
  else
34
36
  AssetCloud::Metadata.new(false)
35
37
  end
@@ -47,11 +49,11 @@ module AssetCloud
47
49
  end
48
50
 
49
51
  def find_record(key)
50
- records.first(:conditions => {self.key_attribute => key.to_s})
52
+ records.first(conditions: { key_attribute => key.to_s })
51
53
  end
52
54
 
53
55
  def find_record!(key)
54
- find_record(key) or raise(AssetCloud::AssetNotFoundError, key)
56
+ find_record(key) || raise(AssetCloud::AssetNotFoundError, key)
55
57
  end
56
58
  end
57
59
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AssetCloud
2
4
  class BlackholeBucket < Bucket
3
5
  def ls(namespace = nil)
@@ -1,61 +1,70 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AssetCloud
2
4
  class BucketChain < Bucket
3
- # returns a new Bucket class which writes to each given Bucket
4
- # but only uses the first one for reading
5
- def self.chain(*klasses)
6
- Class.new(self) do
7
- attr_reader :chained_buckets
8
- define_method 'initialize' do |cloud, name|
9
- super(cloud, name)
10
- @chained_buckets = klasses.map {|klass| klass.new(cloud,name)}
5
+ class << self
6
+ # returns a new Bucket class which writes to each given Bucket
7
+ # but only uses the first one for reading
8
+ def chain(*klasses)
9
+ Class.new(self) do
10
+ attr_reader :chained_buckets
11
+
12
+ define_method "initialize" do |cloud, name|
13
+ super(cloud, name)
14
+ @chained_buckets = klasses.map { |klass| klass.new(cloud, name) }
15
+ end
11
16
  end
12
17
  end
13
18
  end
14
19
 
15
- def ls(key=nil)
16
- first_possible_bucket {|b| b.ls(key)}
20
+ def ls(key = nil)
21
+ first_possible_bucket { |b| b.ls(key) }
17
22
  end
23
+
18
24
  def read(key)
19
- first_possible_bucket {|b| b.read(key)}
25
+ first_possible_bucket { |b| b.read(key) }
20
26
  end
21
- def stat(key=nil)
22
- first_possible_bucket {|b| b.stat(key)}
27
+
28
+ def stat(key = nil)
29
+ first_possible_bucket { |b| b.stat(key) }
23
30
  end
31
+
24
32
  def read_version(key, version)
25
- first_possible_bucket {|b| b.read_version(key, version)}
33
+ first_possible_bucket { |b| b.read_version(key, version) }
26
34
  end
35
+
27
36
  def versions(key)
28
- first_possible_bucket {|b| b.versions(key)}
37
+ first_possible_bucket { |b| b.versions(key) }
29
38
  end
30
39
 
31
40
  def write(key, data)
32
- every_bucket_with_transaction_on_key(key) {|b| b.write(key, data)}
41
+ every_bucket_with_transaction_on_key(key) { |b| b.write(key, data) }
33
42
  end
43
+
34
44
  def delete(key)
35
- every_bucket_with_transaction_on_key(key) {|b| b.delete(key)}
45
+ every_bucket_with_transaction_on_key(key) { |b| b.delete(key) }
36
46
  end
37
47
 
38
- def respond_to?(sym)
39
- @chained_buckets.any? {|b| b.respond_to?(sym)}
48
+ def respond_to_missing?(sym, *)
49
+ @chained_buckets.any? { |b| b.respond_to?(sym) }
40
50
  end
51
+
41
52
  def method_missing(sym, *args)
42
- first_possible_bucket {|b| b.send(sym, *args)}
53
+ first_possible_bucket { |b| b.send(sym, *args) }
43
54
  end
44
55
 
45
56
  private
46
57
 
47
58
  def first_possible_bucket(&block)
48
59
  @chained_buckets.each do |bucket|
49
- begin
50
- return yield(bucket)
51
- rescue NoMethodError, NotImplementedError => e
52
- nil
53
- end
60
+ return yield(bucket)
61
+ rescue NoMethodError, NotImplementedError
62
+ nil
54
63
  end
55
64
  end
56
65
 
57
- def every_bucket_with_transaction_on_key(key, i=0, &block)
58
- return unless bucket = @chained_buckets[i]
66
+ def every_bucket_with_transaction_on_key(key, i = 0, &block)
67
+ return unless (bucket = @chained_buckets[i])
59
68
 
60
69
  old_value = begin
61
70
  bucket.read(key)
@@ -65,8 +74,8 @@ module AssetCloud
65
74
  result = yield(bucket)
66
75
 
67
76
  begin
68
- every_bucket_with_transaction_on_key(key, i+1, &block)
69
- return result
77
+ every_bucket_with_transaction_on_key(key, i + 1, &block)
78
+ result
70
79
  rescue StandardError => e
71
80
  if old_value
72
81
  bucket.write(key, old_value)
@@ -76,7 +85,5 @@ module AssetCloud
76
85
  raise e
77
86
  end
78
87
  end
79
-
80
88
  end
81
-
82
89
  end
@@ -1,27 +1,29 @@
1
- module AssetCloud
1
+ # frozen_string_literal: true
2
2
 
3
+ module AssetCloud
3
4
  class FileSystemBucket < Bucket
4
-
5
5
  def ls(key = nil)
6
6
  objects = []
7
- base_path = File.join(path_for(key), '*')
7
+ base_path = File.join(path_for(key), "*")
8
8
 
9
9
  Dir.glob(base_path).each do |f|
10
10
  next unless File.file?(f)
11
- objects.push cloud[relative_path_for(f)]
11
+
12
+ objects.push(cloud[relative_path_for(f)])
12
13
  end
13
14
  objects
14
15
  end
15
16
 
16
17
  def read(key)
17
18
  File.read(path_for(key))
18
- rescue Errno::ENOENT => e
19
+ rescue Errno::ENOENT
19
20
  raise AssetCloud::AssetNotFoundError, key
20
21
  end
21
22
 
22
23
  def delete(key)
23
24
  File.delete(path_for(key))
24
25
  rescue Errno::ENOENT
26
+ nil
25
27
  end
26
28
 
27
29
  def write(key, data)
@@ -32,12 +34,10 @@ module AssetCloud
32
34
  end
33
35
 
34
36
  def stat(key)
35
- begin
36
- stat = File.stat(path_for(key))
37
- Metadata.new(true, stat.size, stat.ctime, stat.mtime)
38
- rescue Errno::ENOENT => e
39
- Metadata.new(false)
40
- end
37
+ stat = File.stat(path_for(key))
38
+ Metadata.new(true, stat.size, stat.ctime, stat.mtime)
39
+ rescue Errno::ENOENT
40
+ Metadata.new(false)
41
41
  end
42
42
 
43
43
  protected
@@ -53,11 +53,11 @@ module AssetCloud
53
53
  private
54
54
 
55
55
  def remove_full_path_regexp
56
- @regexp ||= /^#{path}\//
56
+ @regexp ||= %r{^#{path}/}
57
57
  end
58
58
 
59
59
  def relative_path_for(f)
60
- f.sub(remove_full_path_regexp, '')
60
+ f.sub(remove_full_path_regexp, "")
61
61
  end
62
62
 
63
63
  def execute_in_full_path(key, &block)
@@ -71,10 +71,9 @@ module AssetCloud
71
71
 
72
72
  begin
73
73
  yield(path)
74
- rescue Errno::ENOENT => e
74
+ rescue Errno::ENOENT
75
75
  raise if retried
76
76
 
77
- directory = File.dirname(path)
78
77
  FileUtils.mkdir_p(File.dirname(path))
79
78
  retried = true
80
79
  retry
@@ -31,12 +31,10 @@ module AssetCloud
31
31
  end
32
32
 
33
33
  def stat(key)
34
- begin
35
- file = find_by_key!(key)
36
- Metadata.new(true, file.size, file.created_at, file.updated_at)
37
- rescue AssetCloud::AssetNotFoundError
38
- Metadata.new(false)
39
- end
34
+ file = find_by_key!(key)
35
+ Metadata.new(true, file.size, file.created_at, file.updated_at)
36
+ rescue AssetCloud::AssetNotFoundError
37
+ Metadata.new(false)
40
38
  end
41
39
 
42
40
  private
@@ -47,11 +45,11 @@ module AssetCloud
47
45
 
48
46
  def absolute_key(key = nil)
49
47
  if key.to_s.starts_with?(path_prefix)
50
- return key
48
+ key
51
49
  else
52
50
  args = [path_prefix]
53
51
  args << key.to_s if key
54
- args.join('/')
52
+ args.join("/")
55
53
  end
56
54
  end
57
55
 
@@ -1,28 +1,31 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AssetCloud
2
4
  class InvalidBucketError < StandardError
3
5
  end
4
6
 
5
7
  class InvalidBucket < Bucket
6
- Error = "No such namespace: %s".freeze
8
+ ERROR = "No such namespace: %s"
9
+ private_constant :ERROR
7
10
 
8
11
  def ls(namespace)
9
- raise InvalidBucketError, Error % namespace
12
+ raise InvalidBucketError, ERROR % namespace
10
13
  end
11
14
 
12
15
  def read(key)
13
- raise InvalidBucketError, Error % key
16
+ raise InvalidBucketError, ERROR % key
14
17
  end
15
18
 
16
19
  def write(key, data)
17
- raise InvalidBucketError, Error % key
20
+ raise InvalidBucketError, ERROR % key
18
21
  end
19
22
 
20
23
  def delete(key)
21
- raise InvalidBucketError, Error % key
24
+ raise InvalidBucketError, ERROR % key
22
25
  end
23
26
 
24
27
  def stat(key)
25
- raise InvalidBucketError, Error % key
28
+ raise InvalidBucketError, ERROR % key
26
29
  end
27
30
  end
28
31
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AssetCloud
2
4
  class MemoryBucket < Bucket
3
5
  def initialize(*args)
@@ -5,16 +7,17 @@ module AssetCloud
5
7
  @memory = {}
6
8
  end
7
9
 
8
- def ls(prefix=nil)
10
+ def ls(prefix = nil)
9
11
  results = []
10
- @memory.each do |k,v|
12
+ @memory.each do |k, _v|
11
13
  results.push(cloud[k]) if prefix.nil? || k.starts_with?(prefix)
12
14
  end
13
15
  results
14
16
  end
15
17
 
16
18
  def read(key)
17
- raise AssetCloud::AssetNotFoundError, key unless @memory.has_key?(key)
19
+ raise AssetCloud::AssetNotFoundError, key unless @memory.key?(key)
20
+
18
21
  @memory[key]
19
22
  end
20
23
 
@@ -29,7 +32,7 @@ module AssetCloud
29
32
  end
30
33
 
31
34
  def stat(key)
32
- return Metadata.non_existing unless @memory.has_key?(key)
35
+ return Metadata.non_existing unless @memory.key?(key)
33
36
 
34
37
  Metadata.new(true, read(key).size)
35
38
  end