asset_cloud 2.7.1 → 2.7.2
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.
- 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
|