bfs-s3 0.7.5 → 0.8.3
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/lib/bfs/bucket/s3.rb +39 -18
- data/spec/bfs/bucket/s3_spec.rb +14 -13
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fde16d5ecd59f0ba7892b75083f66886361e5b7dc5efea15f5c28c2cdd7f0b44
|
4
|
+
data.tar.gz: e5fc5fb205274be7c10071dbc2a8c9c6bbe7c12cc30c90cb0768b1758692183c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 720120b887769f077a4a5f2ac1874cb71f6c2bc9f11825be5aa41096787d226e50ba18008409a0fad45dbe608f61ac7a1ae0314fb811261e7bd2d09bdbfb2a5b
|
7
|
+
data.tar.gz: 3c45d88593ebf385de8cc81c292cd86219ea13d8a6d962cf40b96ff06d34bd5188ab97af85b642beb5be39fffb9503cdf41f2fffe03ae23a9574145047c550bb
|
data/lib/bfs/bucket/s3.rb
CHANGED
@@ -33,22 +33,19 @@ module BFS
|
|
33
33
|
|
34
34
|
# Lists the contents of a bucket using a glob pattern
|
35
35
|
def ls(pattern = '**/*', **opts)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
Enumerator.new do |acc|
|
37
|
+
walk(pattern, **opts) do |path, _|
|
38
|
+
acc << path
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
y << name if File.fnmatch?(pattern, name, File::FNM_PATHNAME)
|
49
|
-
end
|
50
|
-
next_token = resp.next_continuation_token.to_s
|
51
|
-
break if next_token.empty?
|
43
|
+
# Iterates over the contents of a bucket using a glob pattern
|
44
|
+
def glob(pattern = '**/*', **opts)
|
45
|
+
Enumerator.new do |acc|
|
46
|
+
walk(pattern, **opts) do |path, obj|
|
47
|
+
info = BFS::FileInfo.new(path: path, size: obj.size, mtime: obj.last_modified)
|
48
|
+
acc << info
|
52
49
|
end
|
53
50
|
end
|
54
51
|
end
|
@@ -60,7 +57,7 @@ module BFS
|
|
60
57
|
info = @client.head_object(**opts)
|
61
58
|
raise BFS::FileNotFound, path unless info
|
62
59
|
|
63
|
-
BFS::FileInfo.new
|
60
|
+
BFS::FileInfo.new path: path, size: info.content_length, mtime: info.last_modified, content_type: info.content_type, metadata: norm_meta(info.metadata)
|
64
61
|
rescue Aws::S3::Errors::NoSuchKey, Aws::S3::Errors::NoSuchBucket, Aws::S3::Errors::NotFound
|
65
62
|
raise BFS::FileNotFound, path
|
66
63
|
end
|
@@ -82,7 +79,7 @@ module BFS
|
|
82
79
|
opts[:server_side_encryption] ||= @sse if @sse
|
83
80
|
opts[:storage_class] ||= @storage_class if @storage_class
|
84
81
|
|
85
|
-
BFS::
|
82
|
+
BFS::Writer.new(path, encoding: encoding, perm: perm) do |t|
|
86
83
|
File.open(t, encoding: encoding) do |file|
|
87
84
|
@client.put_object(opts.merge(body: file))
|
88
85
|
end
|
@@ -144,9 +141,33 @@ module BFS
|
|
144
141
|
config[:credentials] = opts[:credentials] if opts[:credentials]
|
145
142
|
config[:credentials] ||= Aws::Credentials.new(opts[:access_key_id].to_s, opts[:secret_access_key].to_s) if opts[:access_key_id]
|
146
143
|
config[:credentials] ||= Aws::SharedCredentials.new(profile_name: opts[:profile_name]) if opts[:profile_name]
|
144
|
+
config[:credentials] = Aws::AssumeRoleCredentials.new(
|
145
|
+
client: config[:credentials] ? Aws::STS::Client.new(credentials: config[:credentials]) : nil,
|
146
|
+
role_arn: opts[:assume_role],
|
147
|
+
role_session_name: SecureRandom.urlsafe_base64(12),
|
148
|
+
) if opts[:assume_role]
|
147
149
|
|
148
150
|
Aws::S3::Client.new(config)
|
149
151
|
end
|
152
|
+
|
153
|
+
def walk(pattern, **opts)
|
154
|
+
prefix = pattern[%r{^[^*?\{\}\[\]]+/}]
|
155
|
+
prefix = File.join(*[@prefix, prefix].compact) if @prefix
|
156
|
+
|
157
|
+
opts = opts.merge(bucket: name, prefix: @prefix)
|
158
|
+
opts[:prefix] = prefix if prefix
|
159
|
+
|
160
|
+
next_token = nil
|
161
|
+
loop do
|
162
|
+
resp = @client.list_objects_v2 opts.merge(continuation_token: next_token)
|
163
|
+
resp.contents.each do |obj|
|
164
|
+
path = trim_prefix(obj.key)
|
165
|
+
yield(path, obj) if File.fnmatch?(pattern, path, File::FNM_PATHNAME)
|
166
|
+
end
|
167
|
+
next_token = resp.next_continuation_token.to_s
|
168
|
+
break if next_token.empty?
|
169
|
+
end
|
170
|
+
end
|
150
171
|
end
|
151
172
|
end
|
152
173
|
end
|
@@ -154,7 +175,7 @@ end
|
|
154
175
|
BFS.register('s3') do |url, opts, block|
|
155
176
|
prefix = BFS.norm_path(opts[:prefix] || url.path)
|
156
177
|
opts[:prefix] = prefix.empty? ? nil : prefix
|
157
|
-
opts = opts.slice(:prefix, :region, :sse, :access_key_id, :secret_access_key, :acl, :storage_class, :encoding)
|
178
|
+
opts = opts.slice(:prefix, :region, :sse, :access_key_id, :secret_access_key, :acl, :storage_class, :encoding, :assume_role)
|
158
179
|
|
159
180
|
BFS::Bucket::S3.open url.host, **opts, &block
|
160
181
|
end
|
data/spec/bfs/bucket/s3_spec.rb
CHANGED
@@ -1,38 +1,39 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
bucket_name = 'bsm-bfs-unittest'
|
4
4
|
|
5
5
|
RSpec.describe BFS::Bucket::S3, s3: true do
|
6
|
-
let(:prefix) { "x/#{SecureRandom.uuid}/" }
|
7
|
-
|
8
6
|
subject do
|
9
|
-
described_class.new
|
7
|
+
described_class.new bucket_name, prefix: prefix
|
10
8
|
end
|
11
|
-
|
12
|
-
|
9
|
+
|
10
|
+
let(:prefix) { "x/#{SecureRandom.uuid}/" }
|
11
|
+
|
12
|
+
after do
|
13
|
+
bucket = described_class.new bucket_name, prefix: prefix
|
13
14
|
bucket.ls.each {|name| bucket.rm(name) }
|
14
15
|
end
|
15
16
|
|
16
17
|
it_behaves_like 'a bucket'
|
17
18
|
|
18
|
-
it '
|
19
|
-
bucket = BFS.resolve("s3://#{
|
19
|
+
it 'resolves from URL' do
|
20
|
+
bucket = BFS.resolve("s3://#{bucket_name}/?acl=private&encoding=binary")
|
20
21
|
expect(bucket).to be_instance_of(described_class)
|
21
|
-
expect(bucket.name).to eq(
|
22
|
+
expect(bucket.name).to eq(bucket_name)
|
22
23
|
expect(bucket.acl).to eq(:private)
|
23
24
|
expect(bucket.encoding).to eq('binary')
|
24
25
|
expect(bucket.instance_variable_get(:@prefix)).to be_nil
|
25
26
|
bucket.close
|
26
27
|
|
27
|
-
bucket = BFS.resolve("s3://#{
|
28
|
+
bucket = BFS.resolve("s3://#{bucket_name}/a/b/")
|
28
29
|
expect(bucket).to be_instance_of(described_class)
|
29
|
-
expect(bucket.name).to eq(
|
30
|
+
expect(bucket.name).to eq(bucket_name)
|
30
31
|
expect(bucket.instance_variable_get(:@prefix)).to eq('a/b')
|
31
32
|
bucket.close
|
32
33
|
end
|
33
34
|
|
34
|
-
it '
|
35
|
-
bucket = described_class.new
|
35
|
+
it 'enumerates over a large number of files' do
|
36
|
+
bucket = described_class.new bucket_name, prefix: 'm/'
|
36
37
|
expect(bucket.ls('**/*').count).to eq(2121)
|
37
38
|
bucket.close
|
38
39
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bfs-s3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitrij Denissenko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-s3
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.8.3
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 0.8.3
|
41
41
|
description: https://github.com/bsm/bfs.rb
|
42
42
|
email: dimitrij@blacksquaremedia.com
|
43
43
|
executables: []
|
@@ -67,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
requirements: []
|
70
|
-
rubygems_version: 3.
|
70
|
+
rubygems_version: 3.2.15
|
71
71
|
signing_key:
|
72
72
|
specification_version: 4
|
73
73
|
summary: S3 bucket adapter for bfs
|