bfs 0.7.0 → 0.7.1

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: ff8d42e2ce3e53b671a1210c70ced9c25e96b5ca60effac77ada4868ef26d299
4
- data.tar.gz: 881dd9522385bc0417cb12bf6ab492a9f772dd091042130db614b6252ec29d24
3
+ metadata.gz: 4851ad3e633d9ba6e2e1533206f9810390ff29959d047916f32004c4432bc282
4
+ data.tar.gz: 9129b8d9d6a87a8a5e97bd45145b4936f07bfd27c6c088bad6797477afcbf795
5
5
  SHA512:
6
- metadata.gz: abe8ef5d0579001860159f7485e0cb254d013e10575a2c5fd8b56e3ba94e3766d1b4db0f1843a3261dc50f8f30f15d16115fdabf976a441fb42a81711c4cea1a
7
- data.tar.gz: 98238249263bff71a4d48677296d3e4641d788ab355fdff0a4253792884daf38356cc3823c93b6b4f1bb33de234a80f0043b0c52db75b3d0ffea718d6b510fed
6
+ metadata.gz: 015a5be095930a9f2a4b446809ac4d2684cd4c49ff3b56fc7a28b1f43b2bfe49953625092fcdced43969407d9d40e63eabc6f127fcb58d139d7de55b4b6f98d3
7
+ data.tar.gz: 8a3dcc158679457ba9881a29d47c0e4a1c316b040c2080bba61f80c596f20245125b1071a47c9540f65a588e94cccdf519bf0d975a38693c6b5e89ccee5c9326
data/lib/bfs.rb CHANGED
@@ -40,7 +40,7 @@ module BFS
40
40
  end
41
41
  end
42
42
 
43
- def self.resolve(url)
43
+ def self.resolve(url, &block)
44
44
  url = url.is_a?(::URI) ? url.dup : URI.parse(url)
45
45
  rsl = @registry[url.scheme]
46
46
  raise ArgumentError, "Unable to resolve #{url}, scheme #{url.scheme} is not registered" unless rsl
@@ -49,7 +49,7 @@ module BFS
49
49
  CGI.parse(url.query.to_s).each do |key, values|
50
50
  opts[key.to_sym] = values.first
51
51
  end
52
- rsl.call(url, opts)
52
+ rsl.call(url, opts, block)
53
53
  end
54
54
 
55
55
  def self.norm_path(path)
@@ -64,6 +64,11 @@ module BFS
64
64
  mode = mode.to_i(8) if mode.is_a?(String)
65
65
  mode & 0o000777
66
66
  end
67
+
68
+ def self.defer(obj, method)
69
+ owner = Process.pid
70
+ ObjectSpace.define_finalizer(obj, ->(*) { obj.send(method) if Process.pid == owner })
71
+ end
67
72
  end
68
73
 
69
74
  require 'bfs/helpers'
@@ -3,12 +3,26 @@ module BFS
3
3
  class Blob
4
4
  attr_reader :path
5
5
 
6
+ # Behaves like new, but accepts an optional block.
7
+ # If a block is given, blobs are automatically closed after the block is yielded.
8
+ def self.open(url)
9
+ blob = new(url)
10
+ begin
11
+ yield blob
12
+ ensure
13
+ blob.close
14
+ end if block_given?
15
+ blob
16
+ end
17
+
6
18
  def initialize(url)
7
19
  url = url.is_a?(::URI) ? url.dup : URI.parse(url)
8
20
  @path = BFS.norm_path(url.path)
9
21
 
10
22
  url.path = '/'
11
23
  @bucket = BFS.resolve(url)
24
+
25
+ BFS.defer(self, :close)
12
26
  end
13
27
 
14
28
  # Info returns the blob info.
@@ -34,7 +48,7 @@ module BFS
34
48
 
35
49
  # Shortcut method to read the contents of the blob.
36
50
  def read(**opts)
37
- open(**opts, &:read)
51
+ self.open(**opts, &:read)
38
52
  end
39
53
 
40
54
  # Shortcut method to write data to blob.
@@ -5,6 +5,18 @@ module BFS
5
5
  class Abstract
6
6
  attr_reader :encoding, :perm
7
7
 
8
+ # Behaves like new, but accepts an optional block.
9
+ # If a block is given, buckets are automatically closed after the block is yielded.
10
+ def self.open(*args, **opts)
11
+ bucket = new(*args, **opts)
12
+ begin
13
+ yield bucket
14
+ ensure
15
+ bucket.close
16
+ end if block_given?
17
+ bucket
18
+ end
19
+
8
20
  # Initializes a new bucket
9
21
  # @param [Hash] opts options
10
22
  # @option opts [String] :encoding Custom encoding. Default: Encoding.default_external.
@@ -18,6 +30,8 @@ module BFS
18
30
  when String
19
31
  @perm = perm.to_i(8)
20
32
  end
33
+
34
+ BFS.defer(self, :close)
21
35
  end
22
36
 
23
37
  # Lists the contents of a bucket using a glob pattern
@@ -51,7 +65,7 @@ module BFS
51
65
  # @param [String] path The path to read from.
52
66
  # @param [Hash] opts Additional options, see #open.
53
67
  def read(path, **opts)
54
- open(path, **opts, &:read)
68
+ self.open(path, **opts, &:read)
55
69
  end
56
70
 
57
71
  # Shortcut method to write data to path
@@ -68,7 +82,7 @@ module BFS
68
82
  # @param [String] src The source path.
69
83
  # @param [String] dst The destination path.
70
84
  def cp(src, dst, **opts)
71
- open(src, **opts) do |r|
85
+ self.open(src, **opts) do |r|
72
86
  create(dst, **opts) do |w|
73
87
  IO.copy_stream(r, w)
74
88
  end
@@ -102,7 +102,7 @@ module BFS
102
102
  end
103
103
  end
104
104
 
105
- BFS.register('file') do |url, opts|
105
+ BFS.register('file') do |url, opts, block|
106
106
  parts = [url.host, url.path].compact
107
- BFS::Bucket::FS.new File.join(*parts), **opts
107
+ BFS::Bucket::FS.open(File.join(*parts), **opts, &block)
108
108
  end
@@ -0,0 +1 @@
1
+ require 'bfs/bucket/fs'
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe BFS::Bucket::Abstract do
4
+ it 'should open with a block' do
5
+ sub_class = Class.new(described_class) do
6
+ def close
7
+ @closed = true
8
+ end
9
+
10
+ def closed?
11
+ @closed == true
12
+ end
13
+ end
14
+
15
+ bucket = nil
16
+ sub_class.open do |bkt|
17
+ expect(bkt).not_to be_closed
18
+ bucket = bkt
19
+ end
20
+ expect(bucket).to be_instance_of(sub_class)
21
+ expect(bucket).to be_closed
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe BFS do
4
+ it 'should resolve' do
5
+ bucket = BFS.resolve("file://#{Dir.tmpdir}")
6
+ expect(bucket).to be_instance_of(BFS::Bucket::FS)
7
+ bucket.close
8
+ end
9
+
10
+ it 'should resolve with block' do
11
+ BFS.resolve("file://#{Dir.tmpdir}") do |bucket|
12
+ expect(bucket).to be_instance_of(BFS::Bucket::FS)
13
+ expect(bucket).to receive(:close)
14
+ end
15
+ end
16
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bfs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitrij Denissenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-28 00:00:00.000000000 Z
11
+ date: 2020-07-02 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Minimalist abstraction for bucket storage
14
14
  email: dimitrij@blacksquaremedia.com
@@ -24,11 +24,14 @@ files:
24
24
  - lib/bfs/bucket/fs.rb
25
25
  - lib/bfs/bucket/in_mem.rb
26
26
  - lib/bfs/errors.rb
27
+ - lib/bfs/fs.rb
27
28
  - lib/bfs/helpers.rb
28
29
  - spec/bfs/blob_spec.rb
30
+ - spec/bfs/bucket/abstract_spec.rb
29
31
  - spec/bfs/bucket/fs_spec.rb
30
32
  - spec/bfs/bucket/in_mem_spec.rb
31
33
  - spec/bfs/helpers_spec.rb
34
+ - spec/bfs_spec.rb
32
35
  homepage: https://github.com/bsm/bfs.rb
33
36
  licenses:
34
37
  - Apache-2.0
@@ -48,12 +51,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
48
51
  - !ruby/object:Gem::Version
49
52
  version: '0'
50
53
  requirements: []
51
- rubygems_version: 3.1.2
54
+ rubygems_version: 3.1.4
52
55
  signing_key:
53
56
  specification_version: 4
54
57
  summary: Multi-platform cloud bucket adapter
55
58
  test_files:
56
59
  - spec/bfs/blob_spec.rb
60
+ - spec/bfs/bucket/abstract_spec.rb
57
61
  - spec/bfs/bucket/fs_spec.rb
58
62
  - spec/bfs/bucket/in_mem_spec.rb
59
63
  - spec/bfs/helpers_spec.rb
64
+ - spec/bfs_spec.rb