bfs 0.8.0 → 0.9.0

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: 3de22f9cab6ba21d594854a2fcec49cc215b7c10c6f6b5b9cb1528ba6ce96b59
4
- data.tar.gz: cc3b427ff41229556b7b39a9d0ad5d61afdd0439fa984aafadd0aa9635ac4664
3
+ metadata.gz: 7cbeb0028830b8448bfb4b66054e5a1b9a0389df56e36b9e80063403f692e8d0
4
+ data.tar.gz: 3ebdc9ac4cbbdbc856fb8c5f487f58d8339df57845412b32655323b0f3adee75
5
5
  SHA512:
6
- metadata.gz: 569ac3d4e157eebf08f948eab831f214a900d29a96028a703d541d3fa7de7fdcde6a2cb11413ff802c459ff163cff15feb00c3477abcae7b18d77c302255d529
7
- data.tar.gz: 2804530bcc9aaf60f1b475a6948b357242dc96e15788835e34d6cc1989ec7bda8e0bd66372427ce4aa9d5b923eda5468a9c33087b716ac3ca379f391a6192f43
6
+ metadata.gz: 62c813077440f5b39b90f2b48c587959691ed71668bc99553cd4e3938a32f7b150acea7e7ae800c4b6aa20a9752f1bb38665a5ad60d5c41260b968950ffd8ee7
7
+ data.tar.gz: 40bae544a2be1b32e69d410cd4274613e6fcb538f13752a68ebd4527355d0e1129c3d443b77b057eea303806113aa6b19b27cf49cfde3777b03a7d9fbd83684d
@@ -40,6 +40,11 @@ module BFS
40
40
  raise 'not implemented'
41
41
  end
42
42
 
43
+ # Iterates over the contents of a bucket using a glob pattern
44
+ def glob(_pattern = '**', **_opts)
45
+ raise 'not implemented'
46
+ end
47
+
43
48
  # Info returns the info for a single file
44
49
  def info(_path, **_opts)
45
50
  raise 'not implemented'
@@ -107,7 +112,7 @@ module BFS
107
112
  def norm_meta(meta)
108
113
  norm = {}
109
114
  meta.each do |key, value|
110
- nkey = key.to_s.downcase.split(/-/).map(&:capitalize).join('-')
115
+ nkey = key.to_s.downcase.split('-').map(&:capitalize).join('-')
111
116
  norm[nkey] = value
112
117
  end if meta.is_a?(Hash)
113
118
  norm
data/lib/bfs/bucket/fs.rb CHANGED
@@ -15,19 +15,30 @@ module BFS
15
15
 
16
16
  # Lists the contents of a bucket using a glob pattern
17
17
  def ls(pattern = '**/*', **_opts)
18
- Enumerator.new do |y|
19
- Pathname.glob(@root.join(pattern)) do |pname|
20
- y << trim_prefix(pname.to_s) if pname.file?
18
+ Enumerator.new do |acc|
19
+ walk(pattern) do |path, _|
20
+ acc << path
21
+ end
22
+ end
23
+ end
24
+
25
+ # Iterates over the contents of a bucket using a glob pattern
26
+ def glob(pattern = '**/*', **_opts)
27
+ Enumerator.new do |acc|
28
+ walk(pattern) do |path, stat|
29
+ acc << file_info(path, stat)
21
30
  end
22
31
  end
23
32
  end
24
33
 
25
34
  # Info returns the info for a single file
26
35
  def info(path, **_opts)
27
- full = @root.join(norm_path(path))
28
- path = trim_prefix(full.to_s)
29
- stat = full.stat
30
- BFS::FileInfo.new(path: path, size: stat.size, mtime: stat.mtime, mode: BFS.norm_mode(stat.mode))
36
+ norm = norm_path(path)
37
+ pn = @root.join(norm)
38
+ stat = pn.stat
39
+ raise BFS::FileNotFound, path unless stat.file?
40
+
41
+ file_info(norm, stat)
31
42
  rescue Errno::ENOENT
32
43
  raise BFS::FileNotFound, path
33
44
  end
@@ -93,6 +104,19 @@ module BFS
93
104
  rescue Errno::ENOENT
94
105
  raise BFS::FileNotFound, norm_path(src)
95
106
  end
107
+
108
+ private
109
+
110
+ def walk(pattern)
111
+ Pathname.glob(@root.join(pattern)) do |pn|
112
+ stat = pn.stat
113
+ yield(trim_prefix(pn.to_s), stat) if stat.file?
114
+ end
115
+ end
116
+
117
+ def file_info(path, stat)
118
+ BFS::FileInfo.new(path: path, size: stat.size, mtime: stat.mtime, mode: BFS.norm_mode(stat.mode))
119
+ end
96
120
  end
97
121
  end
98
122
  end
@@ -36,8 +36,17 @@ module BFS
36
36
  # Lists the contents of a bucket using a glob pattern
37
37
  def ls(pattern = '**/*', **_opts)
38
38
  Enumerator.new do |y|
39
- @files.each_key do |key|
40
- y << key if File.fnmatch?(pattern, key, File::FNM_PATHNAME)
39
+ @files.each_key do |path|
40
+ y << path if File.fnmatch?(pattern, path, File::FNM_PATHNAME)
41
+ end
42
+ end
43
+ end
44
+
45
+ # Iterates over the contents of a bucket using a glob pattern
46
+ def glob(pattern = '**/*', **_opts)
47
+ Enumerator.new do |y|
48
+ @files.each_key do |path|
49
+ y << file_info(path) if File.fnmatch?(pattern, path, File::FNM_PATHNAME)
41
50
  end
42
51
  end
43
52
  end
@@ -47,8 +56,7 @@ module BFS
47
56
  path = norm_path(path)
48
57
  raise BFS::FileNotFound, path unless @files.key?(path)
49
58
 
50
- entry = @files[path]
51
- BFS::FileInfo.new(path: path, size: entry.io.size, mtime: entry.mtime, content_type: entry.content_type, metadata: entry.metadata)
59
+ file_info(path)
52
60
  end
53
61
 
54
62
  # Creates a new file and opens it for writing.
@@ -84,6 +92,13 @@ module BFS
84
92
  def rm(path, **_opts)
85
93
  @files.delete(norm_path(path))
86
94
  end
95
+
96
+ private
97
+
98
+ def file_info(path)
99
+ entry = @files[path]
100
+ BFS::FileInfo.new path: path, size: entry.io.size, mtime: entry.mtime, content_type: entry.content_type, metadata: entry.metadata
101
+ end
87
102
  end
88
103
  end
89
104
  end
@@ -2,12 +2,15 @@ require 'spec_helper'
2
2
 
3
3
  RSpec.describe BFS::Blob, core: true do
4
4
  describe 'default' do
5
+ subject { described_class.new('memtest://bucket/path/to/file.txt') }
6
+
5
7
  let(:bucket) { BFS::Bucket::InMem.new }
8
+
6
9
  before { allow(BFS).to receive(:resolve).and_return(bucket) }
7
- subject { described_class.new('memtest://bucket/path/to/file.txt') }
10
+
8
11
  after { subject.close }
9
12
 
10
- it 'should move' do
13
+ it 'moves' do
11
14
  expect(subject.path).to eq('path/to/file.txt')
12
15
  expect { subject.mv('/to/other/path.txt') }.to raise_error(BFS::FileNotFound)
13
16
 
@@ -16,7 +19,7 @@ RSpec.describe BFS::Blob, core: true do
16
19
  expect(subject.path).to eq('to/other/path.txt')
17
20
  end
18
21
 
19
- it 'should write/read' do
22
+ it 'write/reads' do
20
23
  expect { subject.read }.to raise_error(BFS::FileNotFound)
21
24
  subject.write('TESTDATA', content_type: 'text/plain', metadata: { 'x-key' => 'val' })
22
25
 
@@ -36,12 +39,14 @@ RSpec.describe BFS::Blob, core: true do
36
39
  end
37
40
 
38
41
  describe 'file system' do
42
+ subject { described_class.new("file:///#{path}") }
43
+
39
44
  let(:tmpdir) { Dir.mktmpdir }
40
45
  let(:path) { "#{tmpdir}/path/to/file.txt".sub('/', '') }
41
- after { FileUtils.rm_rf tmpdir }
42
- subject { described_class.new("file:///#{path}") }
43
46
 
44
- it 'should move' do
47
+ after { FileUtils.rm_rf tmpdir }
48
+
49
+ it 'moves' do
45
50
  expect(subject.path).to eq(path)
46
51
  expect { subject.mv("#{tmpdir}/to/other/path.txt") }.to raise_error(BFS::FileNotFound)
47
52
 
@@ -54,7 +59,7 @@ RSpec.describe BFS::Blob, core: true do
54
59
  ]
55
60
  end
56
61
 
57
- it 'should write/read' do
62
+ it 'write/reads' do
58
63
  expect { subject.read }.to raise_error(BFS::FileNotFound)
59
64
 
60
65
  subject.write('TESTDATA', content_type: 'text/plain', metadata: { 'x-key' => 'val' })
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe BFS::Bucket::Abstract, core: true do
4
- it 'should open with a block' do
4
+ it 'opens with a block' do
5
5
  sub_class = Class.new(described_class) do
6
6
  def close
7
7
  @closed = true
@@ -1,15 +1,17 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe BFS::Bucket::FS, core: true do
4
- let(:tmpdir) { Dir.mktmpdir }
5
- after { FileUtils.rm_rf tmpdir }
6
4
  subject { described_class.new(tmpdir) }
7
5
 
6
+ let(:tmpdir) { Dir.mktmpdir }
7
+
8
+ after { FileUtils.rm_rf tmpdir }
9
+
8
10
  it_behaves_like 'a bucket',
9
11
  content_type: false,
10
12
  metadata: false
11
13
 
12
- it 'should resolve from URL' do
14
+ it 'resolves from URL' do
13
15
  File.open(File.join(tmpdir, 'test.txt'), 'wb') {|f| f.write 'TESTDATA' }
14
16
 
15
17
  bucket = BFS.resolve("file://#{tmpdir}")
@@ -18,14 +20,14 @@ RSpec.describe BFS::Bucket::FS, core: true do
18
20
  bucket.close
19
21
  end
20
22
 
21
- it 'should support custom perms on #initialize' do
23
+ it 'supports custom perms on #initialize' do
22
24
  blob = BFS::Blob.new("file://#{tmpdir}/test.txt?perm=0666")
23
25
  blob.create {|w| w.write 'foo' }
24
26
  expect(blob.info.mode).to eq(0o666)
25
27
  blob.close
26
28
  end
27
29
 
28
- it 'should support custom perms on #create' do
30
+ it 'supports custom perms on #create' do
29
31
  blob = BFS::Blob.new("file://#{tmpdir}/test.txt")
30
32
  blob.create(perm: 0o666) {|w| w.write 'foo' }
31
33
  expect(blob.info.mode).to eq(0o666)
@@ -1,16 +1,17 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe BFS::Writer, core: true do
4
- let(:on_commit) { proc { true } }
5
4
  subject { described_class.new 'test', &on_commit }
6
5
 
7
- it 'should support custom params' do
6
+ let(:on_commit) { proc { true } }
7
+
8
+ it 'supports custom params' do
8
9
  subject = described_class.new 'test', perm: 0o640, &on_commit
9
10
  expect(subject.stat.mode).to eq(0o100640)
10
11
  expect(subject.commit).to be(true)
11
12
  end
12
13
 
13
- it 'should execute a on_commit block' do
14
+ it 'executes a on_commit block' do
14
15
  expect(on_commit).to receive(:call).with(subject.path).once
15
16
  expect(subject.commit).to be(true)
16
17
  expect(subject.commit).to be(false)
@@ -21,7 +22,7 @@ RSpec.describe BFS::Writer, core: true do
21
22
  expect(subject.discard).to be(true)
22
23
  end
23
24
 
24
- it 'should not auto-commit on close' do
25
+ it 'does not auto-commit on close' do
25
26
  expect(on_commit).not_to receive(:call)
26
27
  expect(subject.close).to be_nil
27
28
  end
data/spec/bfs_spec.rb CHANGED
@@ -1,14 +1,14 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe BFS, core: true do
4
- it 'should resolve' do
5
- bucket = BFS.resolve("file://#{Dir.tmpdir}")
4
+ it 'resolves' do
5
+ bucket = described_class.resolve("file://#{Dir.tmpdir}")
6
6
  expect(bucket).to be_instance_of(BFS::Bucket::FS)
7
7
  bucket.close
8
8
  end
9
9
 
10
- it 'should resolve with block' do
11
- BFS.resolve("file://#{Dir.tmpdir}") do |bucket|
10
+ it 'resolves with block' do
11
+ described_class.resolve("file://#{Dir.tmpdir}") do |bucket|
12
12
  expect(bucket).to be_instance_of(BFS::Bucket::FS)
13
13
  expect(bucket).to receive(:close)
14
14
  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.8.0
4
+ version: 0.9.0
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-12-01 00:00:00.000000000 Z
11
+ date: 2021-06-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Minimalist abstraction for bucket storage
14
14
  email: dimitrij@blacksquaremedia.com
@@ -51,7 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
51
51
  - !ruby/object:Gem::Version
52
52
  version: '0'
53
53
  requirements: []
54
- rubygems_version: 3.1.4
54
+ rubygems_version: 3.2.15
55
55
  signing_key:
56
56
  specification_version: 4
57
57
  summary: Multi-platform cloud bucket adapter