asset_cloud 2.7.1 → 2.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +20 -5
- data/.github/workflows/cla.yml +22 -0
- data/.rubocop.yml +3 -1
- data/Gemfile +5 -3
- data/History.md +4 -0
- data/Rakefile +18 -16
- data/asset_cloud.gemspec +19 -18
- data/dev.yml +1 -1
- data/lib/asset_cloud/asset.rb +17 -13
- data/lib/asset_cloud/asset_extension.rb +27 -15
- data/lib/asset_cloud/base.rb +77 -72
- data/lib/asset_cloud/bucket.rb +5 -2
- data/lib/asset_cloud/buckets/active_record_bucket.rb +16 -14
- data/lib/asset_cloud/buckets/blackhole_bucket.rb +2 -0
- data/lib/asset_cloud/buckets/bucket_chain.rb +38 -31
- data/lib/asset_cloud/buckets/file_system_bucket.rb +14 -15
- data/lib/asset_cloud/buckets/gcs_bucket.rb +6 -8
- data/lib/asset_cloud/buckets/invalid_bucket.rb +9 -6
- data/lib/asset_cloud/buckets/memory_bucket.rb +7 -4
- data/lib/asset_cloud/buckets/s3_bucket.rb +11 -8
- data/lib/asset_cloud/buckets/versioned_memory_bucket.rb +4 -2
- data/lib/asset_cloud/callbacks.rb +7 -3
- data/lib/asset_cloud/free_key_locator.rb +6 -6
- data/lib/asset_cloud/metadata.rb +11 -7
- data/lib/asset_cloud/validations.rb +9 -5
- data/lib/asset_cloud.rb +23 -21
- data/spec/active_record_bucket_spec.rb +27 -26
- data/spec/asset_cloud/metadata_spec.rb +4 -2
- data/spec/asset_extension_spec.rb +17 -16
- data/spec/asset_spec.rb +27 -21
- data/spec/base_spec.rb +93 -92
- data/spec/blackhole_bucket_spec.rb +12 -11
- data/spec/bucket_chain_spec.rb +61 -56
- data/spec/bucket_spec.rb +6 -5
- data/spec/callbacks_spec.rb +41 -39
- data/spec/file_system_spec.rb +25 -24
- data/spec/find_free_key_spec.rb +16 -17
- data/spec/gcs_bucket_remote_spec.rb +23 -22
- data/spec/gcs_bucket_spec.rb +48 -60
- data/spec/memory_bucket_spec.rb +12 -11
- data/spec/mock_s3_interface.rb +17 -6
- data/spec/remote_s3_bucket_spec.rb +31 -28
- data/spec/s3_bucket_spec.rb +19 -17
- data/spec/spec_helper.rb +8 -7
- data/spec/validations_spec.rb +13 -12
- data/spec/versioned_memory_bucket_spec.rb +11 -10
- metadata +9 -32
- data/.github/probots.yml +0 -2
- data/.rubocop_todo.yml +0 -326
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 568dd22b66b6a00beacf0a8d099cad040bcddac422b3932b946573d823e67291
|
4
|
+
data.tar.gz: 8e97aa129cc5c6617722a6f5212ff51562cee437ba22476ceb63d7ad9dc62d25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cde8568299bb0b63c31ce9affa4880bcc7aa1940a63d1541210289f25dc7766528846d110a9b00ae7d1a412bc5bb2e695294b4bff851fb7aa0cc090856ed2bb
|
7
|
+
data.tar.gz: 821d7f7f2fe4c37df691d52b40217168638ff2d2d5cc3ee2dd056ec231e30f44584b1dbd538dc98d167d07d1a29ac0948bbde798d1b7f1870324f593090ecf88
|
data/.github/workflows/ci.yml
CHANGED
@@ -3,12 +3,13 @@ name: CI
|
|
3
3
|
on: [push, pull_request]
|
4
4
|
|
5
5
|
jobs:
|
6
|
-
|
6
|
+
test:
|
7
7
|
runs-on: ubuntu-latest
|
8
8
|
name: Ruby ${{ matrix.ruby }}
|
9
9
|
strategy:
|
10
|
+
fail-fast: false
|
10
11
|
matrix:
|
11
|
-
ruby: ["2.5", "2.6", "2.7"]
|
12
|
+
ruby: ["2.5", "2.6", "2.7", "3.0", "3.1", "3.2"]
|
12
13
|
steps:
|
13
14
|
|
14
15
|
- name: Check out code
|
@@ -20,8 +21,22 @@ jobs:
|
|
20
21
|
ruby-version: ${{ matrix.ruby }}
|
21
22
|
bundler-cache: true
|
22
23
|
|
23
|
-
- name: RuboCop
|
24
|
-
run: bundle exec rubocop || true # until we fix offenses due to outdated config
|
25
|
-
|
26
24
|
- name: Tests
|
27
25
|
run: bundle exec rspec
|
26
|
+
|
27
|
+
lint:
|
28
|
+
runs-on: ubuntu-latest
|
29
|
+
name: RuboCop
|
30
|
+
steps:
|
31
|
+
|
32
|
+
- name: Check out code
|
33
|
+
uses: actions/checkout@v3
|
34
|
+
|
35
|
+
- name: Set up Ruby
|
36
|
+
uses: ruby/setup-ruby@v1
|
37
|
+
with:
|
38
|
+
ruby-version: '3.2'
|
39
|
+
bundler-cache: true
|
40
|
+
|
41
|
+
- name: RuboCop
|
42
|
+
run: bundle exec rubocop
|
@@ -0,0 +1,22 @@
|
|
1
|
+
name: Contributor License Agreement (CLA)
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request_target:
|
5
|
+
types: [opened, synchronize]
|
6
|
+
issue_comment:
|
7
|
+
types: [created]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
cla:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
if: |
|
13
|
+
(github.event.issue.pull_request
|
14
|
+
&& !github.event.issue.pull_request.merged_at
|
15
|
+
&& contains(github.event.comment.body, 'signed')
|
16
|
+
)
|
17
|
+
|| (github.event.pull_request && !github.event.pull_request.merged)
|
18
|
+
steps:
|
19
|
+
- uses: Shopify/shopify-cla-action@v1
|
20
|
+
with:
|
21
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
22
|
+
cla-token: ${{ secrets.CLA_TOKEN }}
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "aws-sdk-s3", ">= 1.60.2", require: false
|
6
|
+
gem "google-cloud-storage"
|
5
7
|
|
6
8
|
gemspec
|
data/History.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Asset Cloud Version History
|
2
2
|
|
3
|
+
## Version 2.7.2, 2023-04-20
|
4
|
+
|
5
|
+
* Swap the order of operations for checking UUID and asset exist logic in free key locator (https://github.com/Shopify/asset_cloud/pull/83)
|
6
|
+
|
3
7
|
## Version 2.7.1, 2022-03-18
|
4
8
|
|
5
9
|
* Fix incorrect invocation of callbacks defined in external classes (https://github.com/Shopify/asset_cloud/issues/71)
|
data/Rakefile
CHANGED
@@ -1,28 +1,30 @@
|
|
1
|
-
|
2
|
-
require 'rspec'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require 'rdoc/task'
|
7
|
-
require 'rspec/core/rake_task'
|
8
|
-
require 'rubocop/rake_task'
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rspec"
|
9
5
|
|
10
|
-
|
6
|
+
require "rake"
|
7
|
+
require "rake/testtask"
|
8
|
+
require "rdoc/task"
|
9
|
+
require "rspec/core/rake_task"
|
10
|
+
require "rubocop/rake_task"
|
11
|
+
|
12
|
+
desc "Default: run unit tests and style checks."
|
11
13
|
task default: [:spec, :rubocop]
|
12
14
|
|
13
15
|
desc "Run all spec examples"
|
14
16
|
RSpec::Core::RakeTask.new do |t|
|
15
|
-
t.pattern =
|
16
|
-
t.rspec_opts = [
|
17
|
+
t.pattern = "spec/**/*_spec.rb"
|
18
|
+
t.rspec_opts = ["--color"]
|
17
19
|
end
|
18
20
|
|
19
|
-
desc
|
21
|
+
desc "Generate documentation for the asset_cloud plugin."
|
20
22
|
Rake::RDocTask.new(:rdoc) do |rdoc|
|
21
|
-
rdoc.rdoc_dir =
|
22
|
-
rdoc.title =
|
23
|
-
rdoc.options <<
|
24
|
-
rdoc.rdoc_files.include(
|
25
|
-
rdoc.rdoc_files.include(
|
23
|
+
rdoc.rdoc_dir = "rdoc"
|
24
|
+
rdoc.title = "AssetCloud"
|
25
|
+
rdoc.options << "--line-numbers" << "--inline-source"
|
26
|
+
rdoc.rdoc_files.include("README")
|
27
|
+
rdoc.rdoc_files.include("lib/**/*.rb")
|
26
28
|
end
|
27
29
|
|
28
30
|
RuboCop::RakeTask.new
|
data/asset_cloud.gemspec
CHANGED
@@ -1,29 +1,30 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
4
|
+
require "English"
|
3
5
|
Gem::Specification.new do |s|
|
4
|
-
s.name =
|
5
|
-
s.version = "2.7.
|
6
|
+
s.name = "asset_cloud"
|
7
|
+
s.version = "2.7.2"
|
6
8
|
|
7
|
-
s.authors =
|
8
|
-
s.summary =
|
9
|
-
s.description =
|
9
|
+
s.authors = ["Shopify"]
|
10
|
+
s.summary = "An abstraction layer around arbitrary and diverse asset stores."
|
11
|
+
s.description = "An abstraction layer around arbitrary and diverse asset stores."
|
10
12
|
|
11
|
-
s.required_ruby_version =
|
13
|
+
s.required_ruby_version = ">= 2.5.0"
|
12
14
|
|
13
|
-
s.email =
|
14
|
-
s.homepage =
|
15
|
-
s.require_paths =
|
15
|
+
s.email = "developers@shopify.com"
|
16
|
+
s.homepage = "http://github.com/Shopify/asset_cloud"
|
17
|
+
s.require_paths = ["lib"]
|
16
18
|
|
17
|
-
s.files =
|
18
|
-
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
19
|
+
s.files = %x(git ls-files).split($INPUT_RECORD_SEPARATOR)
|
19
20
|
|
20
|
-
s.add_dependency
|
21
|
+
s.add_dependency("activesupport")
|
21
22
|
|
22
|
-
s.metadata[
|
23
|
+
s.metadata["allowed_push_host"] = "https://rubygems.org"
|
23
24
|
|
24
|
-
s.add_development_dependency
|
25
|
-
s.add_development_dependency
|
26
|
-
s.add_development_dependency
|
27
|
-
s.add_development_dependency
|
28
|
-
s.add_development_dependency
|
25
|
+
s.add_development_dependency("pry")
|
26
|
+
s.add_development_dependency("pry-byebug")
|
27
|
+
s.add_development_dependency("rake")
|
28
|
+
s.add_development_dependency("rspec")
|
29
|
+
s.add_development_dependency("rubocop-shopify")
|
29
30
|
end
|
data/dev.yml
CHANGED
data/lib/asset_cloud/asset.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module AssetCloud
|
3
4
|
class AssetError < StandardError
|
4
5
|
end
|
5
6
|
|
@@ -8,8 +9,9 @@ module AssetCloud
|
|
8
9
|
|
9
10
|
class Asset
|
10
11
|
include Comparable
|
11
|
-
attr_accessor :key, :
|
12
|
+
attr_accessor :key, :cloud, :new_asset
|
12
13
|
attr_reader :extensions
|
14
|
+
attr_writer :value, :metadata
|
13
15
|
|
14
16
|
def initialize(cloud, key, value = nil, metadata = Metadata.non_existing)
|
15
17
|
@new_asset = true
|
@@ -27,10 +29,12 @@ module AssetCloud
|
|
27
29
|
yield self if block_given?
|
28
30
|
end
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
32
|
+
class << self
|
33
|
+
def at(cloud, key, value = nil, metadata = nil, &block)
|
34
|
+
file = new(cloud, key, value, metadata, &block)
|
35
|
+
file.new_asset = false
|
36
|
+
file
|
37
|
+
end
|
34
38
|
end
|
35
39
|
|
36
40
|
def <=>(other)
|
@@ -42,11 +46,11 @@ module AssetCloud
|
|
42
46
|
end
|
43
47
|
|
44
48
|
def relative_key
|
45
|
-
@key.split("/",2).last
|
49
|
+
@key.split("/", 2).last
|
46
50
|
end
|
47
51
|
|
48
52
|
def relative_key_without_ext
|
49
|
-
relative_key.gsub(/\.[^.]+$/,"")
|
53
|
+
relative_key.gsub(/\.[^.]+$/, "")
|
50
54
|
end
|
51
55
|
|
52
56
|
def dirname
|
@@ -58,7 +62,7 @@ module AssetCloud
|
|
58
62
|
end
|
59
63
|
|
60
64
|
def format
|
61
|
-
extname.sub(
|
65
|
+
extname.sub(".", "")
|
62
66
|
end
|
63
67
|
|
64
68
|
def basename
|
@@ -122,7 +126,7 @@ module AssetCloud
|
|
122
126
|
end
|
123
127
|
|
124
128
|
def store!
|
125
|
-
store
|
129
|
+
store || raise(AssetNotSaved, "Validation failed: #{errors.join(", ")}")
|
126
130
|
end
|
127
131
|
|
128
132
|
def to_param
|
@@ -134,11 +138,11 @@ module AssetCloud
|
|
134
138
|
end
|
135
139
|
|
136
140
|
def url(options = {})
|
137
|
-
cloud.url_for
|
141
|
+
cloud.url_for(key, options)
|
138
142
|
end
|
139
143
|
|
140
144
|
def bucket_name
|
141
|
-
@key.split(
|
145
|
+
@key.split("/").first
|
142
146
|
end
|
143
147
|
|
144
148
|
def bucket
|
@@ -169,7 +173,7 @@ module AssetCloud
|
|
169
173
|
end
|
170
174
|
|
171
175
|
def method_missing(method, *args)
|
172
|
-
if extension = @extensions.find { |e| e.respond_to?(method) }
|
176
|
+
if (extension = @extensions.find { |e| e.respond_to?(method) })
|
173
177
|
extension.public_send(method, *args)
|
174
178
|
else
|
175
179
|
super
|
@@ -1,9 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AssetCloud
|
2
4
|
class AssetExtension
|
3
5
|
class AssetMismatch < StandardError
|
4
6
|
end
|
5
|
-
|
6
|
-
def
|
7
|
+
|
8
|
+
def store
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
def delete
|
13
|
+
true
|
14
|
+
end
|
7
15
|
|
8
16
|
include AssetCloud::Callbacks
|
9
17
|
include AssetCloud::Validations
|
@@ -11,31 +19,35 @@ module AssetCloud
|
|
11
19
|
callback_methods :store, :delete, :validate
|
12
20
|
|
13
21
|
attr_reader :asset
|
14
|
-
|
22
|
+
|
23
|
+
delegate :add_error, to: :asset
|
15
24
|
|
16
25
|
class_attribute :extnames
|
17
26
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
27
|
+
class << self
|
28
|
+
def applies_to(*args)
|
29
|
+
extnames = args.map do |arg|
|
30
|
+
arg = arg.to_s.downcase
|
31
|
+
arg = ".#{arg}" unless arg.starts_with?(".")
|
32
|
+
arg
|
33
|
+
end
|
34
|
+
self.extnames = extnames
|
23
35
|
end
|
24
|
-
self.extnames = extnames
|
25
|
-
end
|
26
36
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
37
|
+
def applies_to_asset?(asset)
|
38
|
+
extnames = self.extnames || []
|
39
|
+
extnames.each do |extname|
|
40
|
+
return true if asset.key.downcase.ends_with?(extname)
|
41
|
+
end
|
42
|
+
false
|
31
43
|
end
|
32
|
-
false
|
33
44
|
end
|
34
45
|
|
35
46
|
def initialize(asset)
|
36
47
|
unless self.class.applies_to_asset?(asset)
|
37
48
|
raise AssetMismatch, "Instances of #{self.class.name} cannot be applied to asset #{asset.key.inspect}"
|
38
49
|
end
|
50
|
+
|
39
51
|
@asset = asset
|
40
52
|
end
|
41
53
|
end
|
data/lib/asset_cloud/base.rb
CHANGED
@@ -1,42 +1,44 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
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 =
|
12
|
+
VALID_PATHS = %r{\A
|
12
13
|
(
|
13
|
-
(\w)
|
14
|
-
|
|
14
|
+
(\w) # Filename can be a single letter or underscore
|
15
|
+
| # OR it is many and follows the below rules
|
15
16
|
(
|
16
|
-
(\.?[\w\[\]\(\)\-\@])
|
17
|
+
(\.?[\w\[\]\(\)\-\@]) # It can start with a dot but it must have a following character
|
17
18
|
(
|
18
|
-
[\w\[\]\(\)\-\@]
|
19
|
+
[\w\[\]\(\)\-\@] # You can have a letter without any following conditions
|
19
20
|
|
|
20
|
-
[\ ][\w\[\]\(\)\-\@\.]
|
21
|
+
[\ ][\w\[\]\(\)\-\@\.] # If there is a space you need to have a normal letter afterward or a dot
|
21
22
|
|
|
22
|
-
[
|
23
|
+
[/][\w\[\]\(\)\-\@] # If there is a slash you need to have a normal letter afterward
|
23
24
|
|
|
24
|
-
[
|
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\[\]\(\)\-\@]+
|
27
|
-
)*
|
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
|
30
|
-
MATCH_BUCKET =
|
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 =
|
39
|
+
self.root_bucket_class = "AssetCloud::FileSystemBucket"
|
38
40
|
class_attribute :root_asset_class
|
39
|
-
self.root_asset_class
|
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
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
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
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
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
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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
|
-
|
78
|
-
|
79
|
-
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
-
|
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
|
-
|
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
|
279
|
+
logger&.info { " [#{self.class.name}] bad key #{e.message}" }
|
274
280
|
raise
|
275
281
|
end
|
276
|
-
|
277
282
|
end
|
278
283
|
end
|