asset_cloud 2.2.6 → 2.2.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b8da870cd7f0377f18b1ae46d7a4e8e69c2e4549f224e28df123f565d9e454d3
4
- data.tar.gz: 190fea72f1ef76ffa7aad5931324be4cfc172903f41826a1485c2e859fae50dc
3
+ metadata.gz: d356abcae5568be4981cdcbb779ba94471a67f942f048ee96119e9b9260cf366
4
+ data.tar.gz: 3923b527fe0e5c7e670641f53c6397723465a02877431b50e8e7da20bc67ee74
5
5
  SHA512:
6
- metadata.gz: fb1dff12c4fb90328182f23c96daf17f3f9fddbc13c42dd569b0855545c4be0621aa8bd218c43fc57eb44716f27026e1ca703fea67cd214231ee654853decca6
7
- data.tar.gz: e29ebc045b6eeac9705f5f758aca3fce768c6e9f8085ecc0502cbdecf1037621b504ab0c3c175f61e8faa912d16d5abef16f79c90941c02bbce865e8cc50cae1
6
+ metadata.gz: e8f3a5c2252c2cd574fc55e4feb4aa205a3340e8a43cb945414740be9f6313d422ecc241a8cb8279e48f7b32b6695817576f95779107dd072543c0024d69b33f
7
+ data.tar.gz: 480ada19cbcddae3f9acc2fc46d1022d82b3ba7582534b91aa9f0fe6dc0bbae9efa70f09f5fafd64b95be3e39601ec2b88d2d3bb34b10fe0fe8b7c540f5d0603
@@ -2,5 +2,5 @@ language: ruby
2
2
  before_install:
3
3
  - gem install bundler
4
4
  rvm:
5
- - '2.2'
6
5
  - '2.3'
6
+ - '2.6'
data/Gemfile CHANGED
@@ -1,5 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gem 'aws-sdk', '~> 1.34.0', :require => nil
4
+ gem 'google-cloud-storage'
4
5
 
5
6
  gemspec
@@ -18,6 +18,10 @@ With S3 Remote test:
18
18
 
19
19
  AWS_ACCESS_KEY_ID="<s3_key>" AWS_SECRET_ACCESS_KEY="<s3_secret_key>" S3_BUCKET_NAME="<bucket_name>" bundle exec rake spec
20
20
 
21
+ With GCS Remote test:
22
+
23
+ GCS_PROJECT_ID="<project_id>" GCS_KEY_FILEPATH="<path_to_key>" GCS_BUCKET="<bucket_name>" bundle exec rake spec
24
+
21
25
  == Copyright
22
26
 
23
27
  Copyright (c) 2008-2014 Tobias Lütke & Shopify, Inc. Released under the MIT license (see LICENSE for details).
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{asset_cloud}
5
- s.version = "2.2.6"
5
+ s.version = "2.2.7"
6
6
 
7
7
  s.authors = %w(Shopify)
8
8
  s.summary = %q{An abstraction layer around arbitrary and diverse asset stores.}
@@ -16,6 +16,9 @@ require 'asset_cloud/base'
16
16
  # S3
17
17
  require 'asset_cloud/buckets/s3_bucket'
18
18
 
19
+ # GCS
20
+ require 'asset_cloud/buckets/gcs_bucket'
21
+
19
22
  # Extensions
20
23
  require 'asset_cloud/free_key_locator'
21
24
  require 'asset_cloud/callbacks'
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AssetCloud
4
+ class GCSBucket < Bucket
5
+ def ls(key = nil)
6
+ key ? find_by_key!(key) : bucket.files
7
+ end
8
+
9
+ def read(key)
10
+ file = find_by_key!(key)
11
+ downloaded = file.download
12
+ downloaded.rewind
13
+ downloaded.read
14
+ end
15
+
16
+ def write(key, data)
17
+ bucket.create_file(data, absolute_key(key))
18
+ end
19
+
20
+ def delete(key)
21
+ file = find_by_key!(key)
22
+ file.delete
23
+ end
24
+
25
+ def clear
26
+ bucket.files.each(&:delete)
27
+ end
28
+
29
+ def stat(key)
30
+ begin
31
+ file = find_by_key!(key)
32
+ Metadata.new(true, file.size, file.created_at, file.updated_at)
33
+ rescue AssetCloud::AssetNotFoundError
34
+ Metadata.new(false)
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def bucket
41
+ @bucket ||= cloud.gcs_bucket
42
+ end
43
+
44
+ def absolute_key(key = nil)
45
+ if key.to_s.starts_with?(path_prefix)
46
+ return key
47
+ else
48
+ args = [path_prefix]
49
+ args << key.to_s if key
50
+ args.join('/')
51
+ end
52
+ end
53
+
54
+ def path_prefix
55
+ @path_prefix ||= "s#{@cloud.url}"
56
+ end
57
+
58
+ def find_by_key!(key)
59
+ file = bucket.file(absolute_key(key))
60
+
61
+ raise AssetCloud::AssetNotFoundError, key unless file
62
+
63
+ file
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+ # rubocop:disable RSpec/FilePath, Lint/MissingCopEnableDirective
3
+
4
+ require 'spec_helper'
5
+ require 'google/cloud/storage'
6
+
7
+ class RemoteGCSCloud < AssetCloud::Base
8
+ attr_accessor :gcs_connection
9
+ bucket :tmp, AssetCloud::GCSBucket
10
+
11
+ def gcs_bucket
12
+ gcs_connection.bucket(ENV['GCS_BUCKET'])
13
+ end
14
+ end
15
+
16
+ describe AssetCloud::GCSBucket, if: ENV['GCS_PROJECT_ID'] && ENV['GCS_KEY_FILEPATH'] && ENV['GCS_BUCKET'] do
17
+ directory = File.dirname(__FILE__) + '/files'
18
+
19
+ before(:all) do
20
+ @cloud = RemoteGCSCloud.new(directory, 'assets/files')
21
+
22
+ @cloud.gcs_connection = Google::Cloud::Storage.new(
23
+ project_id: ENV['GCS_PROJECT_ID'],
24
+ credentials: ENV['GCS_KEY_FILEPATH']
25
+ )
26
+ @bucket = @cloud.buckets[:tmp]
27
+ end
28
+
29
+ after(:all) do
30
+ @bucket.clear
31
+ end
32
+
33
+ it "#ls with no arguments returns all files in the bucket" do
34
+ expect_any_instance_of(Google::Cloud::Storage::Bucket).to receive(:files).with(no_args)
35
+ expect do
36
+ @bucket.ls
37
+ end.not_to raise_error
38
+ end
39
+
40
+ it "#ls with arguments returns the file" do
41
+ local_path = "#{directory}/products/key.txt"
42
+ key = 'test/ls.txt'
43
+
44
+ @bucket.write(key, local_path)
45
+
46
+ file = @bucket.ls(key)
47
+ expect(file.name).to eq("s#{@cloud.url}/#{key}")
48
+ end
49
+
50
+ it "#write writes a file into the bucket" do
51
+ local_path = "#{directory}/products/key.txt"
52
+ key = 'test/key.txt'
53
+
54
+ @bucket.write(key, local_path)
55
+ end
56
+
57
+ it "#delete removes the file from the bucket" do
58
+ key = 'test/key.txt'
59
+
60
+ expect do
61
+ @bucket.delete(key)
62
+ end.not_to raise_error
63
+ end
64
+
65
+ it "#delete raises AssetCloud::AssetNotFoundError if the file is not found" do
66
+ key = 'tmp/not_found.txt'
67
+ expect do
68
+ @bucket.delete(key)
69
+ end.to raise_error(AssetCloud::AssetNotFoundError)
70
+ end
71
+
72
+ it "#read returns the data of the file" do
73
+ value = 'hello world'
74
+ key = 'tmp/new_file.txt'
75
+ @bucket.write(key, StringIO.new(value))
76
+
77
+ data = @bucket.read(key)
78
+ data.should == value
79
+ end
80
+
81
+ it "#read raises AssetCloud::AssetNotFoundError if the file is not found" do
82
+ key = 'tmp/not_found.txt'
83
+ expect do
84
+ @bucket.read(key)
85
+ end.to raise_error(AssetCloud::AssetNotFoundError)
86
+ end
87
+
88
+ it "#stats returns metadata of the asset" do
89
+ value = 'hello world'
90
+ key = 'tmp/new_file.txt'
91
+ @bucket.write(key, StringIO.new(value))
92
+
93
+ stats = @bucket.stat(key)
94
+
95
+ expect(stats.size).not_to be_nil
96
+ expect(stats.created_at).not_to be_nil
97
+ expect(stats.updated_at).not_to be_nil
98
+ end
99
+ end
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+ require 'google/cloud/storage'
3
+
4
+ class GCSCloud < AssetCloud::Base
5
+ end
6
+
7
+ class MockGCSBucket < AssetCloud::GCSBucket
8
+ def files(prefix: nil)
9
+ end
10
+
11
+ def file(key)
12
+ end
13
+
14
+ def create_file(data, key)
15
+ end
16
+ end
17
+
18
+ describe AssetCloud::GCSBucket do
19
+ directory = File.dirname(__FILE__) + '/files'
20
+
21
+ before(:all) do
22
+ @cloud = GCSCloud.new(directory, '/assets/files')
23
+ @bucket = MockGCSBucket.new(@cloud, '')
24
+ end
25
+
26
+ it "#ls with no arguments returns all files in the bucket" do
27
+ expect_any_instance_of(GCSCloud).to receive(:gcs_bucket).and_return(@bucket)
28
+ expect_any_instance_of(MockGCSBucket).to receive(:files).with(no_args).and_return(nil)
29
+ @bucket.ls
30
+ end
31
+
32
+ it "#ls with arguments returns the file" do
33
+ key = 'test/ls.txt'
34
+ expect_any_instance_of(MockGCSBucket).to receive(:file).with("s#{@cloud.url}/#{key}").and_return(Google::Cloud::Storage::File.new)
35
+
36
+ file = @bucket.ls(key)
37
+ expect(file.class).to eq(Google::Cloud::Storage::File)
38
+ end
39
+
40
+ it "#write writes a file into the bucket" do
41
+ local_path = "#{directory}/products/key.txt"
42
+ key = 'test/key.txt'
43
+ expect_any_instance_of(MockGCSBucket).to receive(:create_file).with(local_path, "s#{@cloud.url}/#{key}")
44
+
45
+ @bucket.write(key, local_path)
46
+ end
47
+
48
+ it "#delete removes the file from the bucket" do
49
+ key = 'test/key.txt'
50
+ expect_any_instance_of(MockGCSBucket).to receive(:file).with("s#{@cloud.url}/#{key}").and_return(Google::Cloud::Storage::File.new)
51
+ expect_any_instance_of(Google::Cloud::Storage::File).to receive(:delete).with(no_args)
52
+
53
+ expect do
54
+ @bucket.delete(key)
55
+ end.not_to raise_error
56
+ end
57
+
58
+ it "#read returns the data of the file" do
59
+ value = 'hello world'
60
+ key = 'tmp/new_file.txt'
61
+ expect_any_instance_of(MockGCSBucket).to receive(:file).with("s#{@cloud.url}/#{key}").and_return(Google::Cloud::Storage::File.new)
62
+ expect_any_instance_of(Google::Cloud::Storage::File).to receive(:download).and_return(StringIO.new(value))
63
+
64
+ data = @bucket.read(key)
65
+ data.should == value
66
+ end
67
+
68
+ it "#read raises AssetCloud::AssetNotFoundError if the file is not found" do
69
+ key = 'tmp/not_found.txt'
70
+ expect_any_instance_of(MockGCSBucket).to receive(:file).with("s#{@cloud.url}/#{key}").and_return(nil)
71
+ expect do
72
+ @bucket.read(key)
73
+ end.to raise_error(AssetCloud::AssetNotFoundError)
74
+ end
75
+
76
+ it "#stat returns information on the asset" do
77
+ value = 'hello world'
78
+ key = 'tmp/new_file.txt'
79
+ expected_time = Time.now
80
+ expected_size = 1
81
+
82
+ expect_any_instance_of(MockGCSBucket).to receive(:file).with("s#{@cloud.url}/#{key}").and_return(Google::Cloud::Storage::File.new)
83
+ expect_any_instance_of(Google::Cloud::Storage::File).to receive(:size).and_return(expected_size)
84
+ expect_any_instance_of(Google::Cloud::Storage::File).to receive(:created_at).and_return(expected_time)
85
+ expect_any_instance_of(Google::Cloud::Storage::File).to receive(:updated_at).and_return(expected_time)
86
+
87
+ stats = @bucket.stat(key)
88
+ expect(stats.size).to eq(expected_size)
89
+ expect(stats.created_at).to eq(expected_time)
90
+ expect(stats.updated_at).to eq(expected_time)
91
+ end
92
+ end
@@ -5,3 +5,4 @@ require 'active_support/all'
5
5
  $:<< File.dirname(__FILE__) + "/../lib"
6
6
  require 'asset_cloud'
7
7
  require 'asset_cloud/buckets/s3_bucket'
8
+ require 'asset_cloud/buckets/gcs_bucket'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asset_cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.6
4
+ version: 2.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-09 00:00:00.000000000 Z
11
+ date: 2019-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -119,6 +119,7 @@ files:
119
119
  - lib/asset_cloud/buckets/blackhole_bucket.rb
120
120
  - lib/asset_cloud/buckets/bucket_chain.rb
121
121
  - lib/asset_cloud/buckets/file_system_bucket.rb
122
+ - lib/asset_cloud/buckets/gcs_bucket.rb
122
123
  - lib/asset_cloud/buckets/invalid_bucket.rb
123
124
  - lib/asset_cloud/buckets/memory_bucket.rb
124
125
  - lib/asset_cloud/buckets/s3_bucket.rb
@@ -140,6 +141,8 @@ files:
140
141
  - spec/files/products/key.txt
141
142
  - spec/files/versioned_stuff/foo
142
143
  - spec/find_free_key_spec.rb
144
+ - spec/gcs_bucket_remote_spec.rb
145
+ - spec/gcs_bucket_spec.rb
143
146
  - spec/memory_bucket_spec.rb
144
147
  - spec/mock_s3_interface.rb
145
148
  - spec/remote_s3_bucket_spec.rb
@@ -165,8 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
168
  - !ruby/object:Gem::Version
166
169
  version: '0'
167
170
  requirements: []
168
- rubyforge_project:
169
- rubygems_version: 2.7.6
171
+ rubygems_version: 3.0.3
170
172
  signing_key:
171
173
  specification_version: 4
172
174
  summary: An abstraction layer around arbitrary and diverse asset stores.
@@ -183,6 +185,8 @@ test_files:
183
185
  - spec/files/products/key.txt
184
186
  - spec/files/versioned_stuff/foo
185
187
  - spec/find_free_key_spec.rb
188
+ - spec/gcs_bucket_remote_spec.rb
189
+ - spec/gcs_bucket_spec.rb
186
190
  - spec/memory_bucket_spec.rb
187
191
  - spec/mock_s3_interface.rb
188
192
  - spec/remote_s3_bucket_spec.rb