bfs 0.6.1 → 0.7.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: 13963edd5c68d92d4f5ce4ef5c3f3ef0131ddb318b36f4d7114e3e49e4a16a3b
4
- data.tar.gz: b805a46a30c795dd6dc9c8761876a4af5bd73dcc117a2f7c76c8acea7a957ed9
3
+ metadata.gz: ff8d42e2ce3e53b671a1210c70ced9c25e96b5ca60effac77ada4868ef26d299
4
+ data.tar.gz: 881dd9522385bc0417cb12bf6ab492a9f772dd091042130db614b6252ec29d24
5
5
  SHA512:
6
- metadata.gz: cd9c768fed6d9efa36379f9151c4066931cc92267d032b1b0e920c7150b7db108acb739ecd46b5e8c5853b0ff090767b259e35b0d98b1707fa41491c3eb9dd9e
7
- data.tar.gz: 123205693490cd8ee1394be308f28944d84e10098dae690cd54d3bf073710d2f538d397960b19d4d0c33ec271bdbbea3df796bd086733d57f9d28db2c52e7bd6
6
+ metadata.gz: abe8ef5d0579001860159f7485e0cb254d013e10575a2c5fd8b56e3ba94e3766d1b4db0f1843a3261dc50f8f30f15d16115fdabf976a441fb42a81711c4cea1a
7
+ data.tar.gz: 98238249263bff71a4d48677296d3e4641d788ab355fdff0a4253792884daf38356cc3823c93b6b4f1bb33de234a80f0043b0c52db75b3d0ffea718d6b510fed
@@ -15,5 +15,5 @@ Gem::Specification.new do |s|
15
15
  s.files = `git ls-files`.split("\n")
16
16
  s.test_files = `git ls-files -- spec/*`.split("\n")
17
17
  s.require_paths = ['lib']
18
- s.required_ruby_version = '>= 2.5.0'
18
+ s.required_ruby_version = '>= 2.6.0'
19
19
  end
data/lib/bfs.rb CHANGED
@@ -1,7 +1,37 @@
1
1
  require 'uri'
2
+ require 'cgi'
2
3
 
3
4
  module BFS
4
- FileInfo = Struct.new(:path, :size, :mtime, :content_type, :metadata)
5
+ class FileInfo < Hash
6
+ def initialize(**attrs)
7
+ update(size: 0, mtime: Time.at(0), mode: 0, metadata: {})
8
+ update(attrs)
9
+ end
10
+
11
+ def path
12
+ fetch(:path, nil)
13
+ end
14
+
15
+ def size
16
+ fetch(:size, 0)
17
+ end
18
+
19
+ def content_type
20
+ fetch(:content_type, nil)
21
+ end
22
+
23
+ def mtime
24
+ fetch(:mtime, Time.at(0))
25
+ end
26
+
27
+ def mode
28
+ fetch(:mode, 0)
29
+ end
30
+
31
+ def metadata
32
+ fetch(:metadata, {})
33
+ end
34
+ end
5
35
 
6
36
  def self.register(*schemes, &resolver)
7
37
  @registry ||= {}
@@ -15,7 +45,11 @@ module BFS
15
45
  rsl = @registry[url.scheme]
16
46
  raise ArgumentError, "Unable to resolve #{url}, scheme #{url.scheme} is not registered" unless rsl
17
47
 
18
- rsl.call(url)
48
+ opts = {}
49
+ CGI.parse(url.query.to_s).each do |key, values|
50
+ opts[key.to_sym] = values.first
51
+ end
52
+ rsl.call(url, opts)
19
53
  end
20
54
 
21
55
  def self.norm_path(path)
@@ -25,6 +59,11 @@ module BFS
25
59
  path.sub!(%r{/+$}, '')
26
60
  path
27
61
  end
62
+
63
+ def self.norm_mode(mode)
64
+ mode = mode.to_i(8) if mode.is_a?(String)
65
+ mode & 0o000777
66
+ end
28
67
  end
29
68
 
30
69
  require 'bfs/helpers'
@@ -3,11 +3,21 @@ require 'bfs'
3
3
  module BFS
4
4
  module Bucket
5
5
  class Abstract
6
+ attr_reader :encoding, :perm
7
+
6
8
  # Initializes a new bucket
7
9
  # @param [Hash] opts options
8
10
  # @option opts [String] :encoding Custom encoding. Default: Encoding.default_external.
9
- def initialize(**opts)
10
- @encoding = opts.delete(:encoding) || Encoding.default_external
11
+ # @option opts [Integer] :perm optional file permissions. Default: 0600.
12
+ def initialize(encoding: Encoding.default_external, perm: nil, **_opts)
13
+ @encoding = encoding
14
+
15
+ case perm
16
+ when Integer
17
+ @perm = perm
18
+ when String
19
+ @perm = perm.to_i(8)
20
+ end
11
21
  end
12
22
 
13
23
  # Lists the contents of a bucket using a glob pattern
@@ -26,7 +26,8 @@ module BFS
26
26
  def info(path, **_opts)
27
27
  full = @root.join(norm_path(path))
28
28
  path = trim_prefix(full.to_s)
29
- BFS::FileInfo.new(path, full.size, full.mtime, nil, {})
29
+ stat = full.stat
30
+ BFS::FileInfo.new(path: path, size: stat.size, mtime: stat.mtime, mode: BFS.norm_mode(stat.mode))
30
31
  rescue Errno::ENOENT
31
32
  raise BFS::FileNotFound, path
32
33
  end
@@ -37,13 +38,11 @@ module BFS
37
38
  # @param [Hash] opts Additional options.
38
39
  # @option opts [String] :encoding Custom encoding.
39
40
  # @option opts [Integer] :perm Custom file permission, default: 0600.
40
- def create(path, **opts, &block)
41
+ def create(path, encoding: self.encoding, perm: self.perm, **_opts, &block)
41
42
  full = @root.join(norm_path(path))
42
43
  FileUtils.mkdir_p(full.dirname.to_s)
43
44
 
44
- perm = opts[:perm]
45
- enc = opts[:encoding] || @encoding
46
- temp = BFS::TempWriter.new(full, perm: perm, encoding: enc) {|t| FileUtils.mv t, full.to_s }
45
+ temp = BFS::TempWriter.new(full, encoding: encoding, perm: perm) {|t| FileUtils.mv t, full.to_s }
47
46
  return temp unless block
48
47
 
49
48
  begin
@@ -103,7 +102,7 @@ module BFS
103
102
  end
104
103
  end
105
104
 
106
- BFS.register('file') do |url|
105
+ BFS.register('file') do |url, opts|
107
106
  parts = [url.host, url.path].compact
108
- BFS::Bucket::FS.new File.join(*parts)
107
+ BFS::Bucket::FS.new File.join(*parts), **opts
109
108
  end
@@ -32,7 +32,7 @@ module BFS
32
32
  raise BFS::FileNotFound, path unless @files.key?(path)
33
33
 
34
34
  entry = @files[path]
35
- BFS::FileInfo.new(path, entry.io.size, entry.mtime, entry.content_type, entry.metadata)
35
+ BFS::FileInfo.new(path: path, size: entry.io.size, mtime: entry.mtime, content_type: entry.content_type, metadata: entry.metadata)
36
36
  end
37
37
 
38
38
  # Creates a new file and opens it for writing.
@@ -42,11 +42,12 @@ module BFS
42
42
  # @option opts [String] :encoding Custom encoding.
43
43
  # @option opts [String] :content_type Custom content type.
44
44
  # @option opts [Hash] :metadata Metadata key-value pairs.
45
- def create(path, **opts, &block)
45
+ def create(path, encoding: self.encoding, content_type: nil, metadata: nil, **_opts, &block)
46
46
  io = StringIO.new
47
- io.set_encoding(opts[:encoding] || @encoding)
47
+ io.set_encoding(encoding)
48
48
 
49
- @files[norm_path(path)] = Entry.new(io, Time.now, opts[:content_type], norm_meta(opts[:metadata]))
49
+ entry = Entry.new(io, Time.now, content_type, norm_meta(metadata))
50
+ @files[norm_path(path)] = entry
50
51
  return io unless block
51
52
 
52
53
  begin
@@ -21,7 +21,14 @@ RSpec.describe BFS::Blob do
21
21
  subject.write('TESTDATA', content_type: 'text/plain', metadata: { 'x-key' => 'val' })
22
22
 
23
23
  info = subject.info
24
- expect(info).to eq(BFS::FileInfo.new('path/to/file.txt', 8, info.mtime, 'text/plain', 'X-Key' => 'val'))
24
+ expect(info).to eq(
25
+ path: 'path/to/file.txt',
26
+ size: 8,
27
+ mtime: info.mtime,
28
+ content_type: 'text/plain',
29
+ mode: 0,
30
+ metadata: { 'X-Key' => 'val' },
31
+ )
25
32
  expect(info.mtime).to be_within(1).of(Time.now)
26
33
 
27
34
  expect(subject.read).to eq('TESTDATA')
@@ -54,7 +61,13 @@ RSpec.describe BFS::Blob do
54
61
  expect(subject.read).to eq('TESTDATA')
55
62
 
56
63
  info = subject.info
57
- expect(info).to eq(BFS::FileInfo.new(path, 8, info.mtime, nil, {}))
64
+ expect(info).to eq(
65
+ path: path,
66
+ size: 8,
67
+ mtime: info.mtime,
68
+ mode: 0o600,
69
+ metadata: {},
70
+ )
58
71
  expect(info.mtime).to be_within(1).of(Time.now)
59
72
 
60
73
  expect(Pathname.glob("#{tmpdir}/**/*").select(&:file?).map(&:to_s)).to eq [
@@ -17,10 +17,17 @@ RSpec.describe BFS::Bucket::FS do
17
17
  expect(bucket.ls.to_a).to eq(['test.txt'])
18
18
  end
19
19
 
20
- it 'should support custom perms' do
20
+ it 'should support custom perms on #initialize' do
21
+ blob = BFS::Blob.new("file://#{tmpdir}/test.txt?perm=0666")
22
+ blob.create {|w| w.write 'foo' }
23
+ expect(blob.info.mode).to eq(0o666)
24
+ blob.close
25
+ end
26
+
27
+ it 'should support custom perms on #create' do
21
28
  blob = BFS::Blob.new("file://#{tmpdir}/test.txt")
22
29
  blob.create(perm: 0o666) {|w| w.write 'foo' }
23
- expect(File.stat(File.join(tmpdir, 'test.txt')).mode).to eq(0o100666)
30
+ expect(blob.info.mode).to eq(0o666)
24
31
  blob.close
25
32
  end
26
33
  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.6.1
4
+ version: 0.7.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-02-11 00:00:00.000000000 Z
11
+ date: 2020-05-28 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Minimalist abstraction for bucket storage
14
14
  email: dimitrij@blacksquaremedia.com
@@ -41,7 +41,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
41
41
  requirements:
42
42
  - - ">="
43
43
  - !ruby/object:Gem::Version
44
- version: 2.5.0
44
+ version: 2.6.0
45
45
  required_rubygems_version: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - ">="