bfs 0.2.1 → 0.2.2

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: 689dbae3e78b15428f90cedacdff7e48fea896ba9af0c4342f6514d64a4efe65
4
- data.tar.gz: 5587c11cf6160b8a6bb60cd3a1d28e78920cc489a131007255988bed4575e933
3
+ metadata.gz: 0b8d15cd430ed129880e1dcae5573b5ec7b9b7998094d950c7650f951c91a336
4
+ data.tar.gz: bd074f7b801ed837dc55db15f1dd7a192f050cc9f0ac7d0fe96ff401cc2dc660
5
5
  SHA512:
6
- metadata.gz: 6184ff146d864c6697fb1957441263f27de7055adf259d02b3bec478f02464aa4ed954f314bc398758424e7cacb7f7e8a8101cf51ab3f0293160487d31cbe4a9
7
- data.tar.gz: c503e81d75a02e8e11a4c9d7a3c0f7d701d51e938ac69e9afeadd0f37d0bde8dd598ad3ddbda2c8b784104bc6ab3dadab431e29a32352d1ad311964023acc213
6
+ metadata.gz: 8a10d11748fe17841ceddbb652f380da9d049c3f41efaed685209f41a47bc8b5d9fba86f5174f434644359a67d3905ca960fd20bc5797512bcad566b2241ab9c
7
+ data.tar.gz: c9ce56c64e7426c62db78750d0ef9e711d3a828c0bb9d901579b66d9f921c52a48cd7c86a86997f374488e3e78d870136165f5da1884addcee719961be2760b3
data/lib/bfs/blob.rb CHANGED
@@ -5,8 +5,10 @@ module BFS
5
5
 
6
6
  def initialize(url)
7
7
  url = URI.parse(url) unless url.is_a?(::URI)
8
+ @path = BFS.norm_path(url.path)
9
+
10
+ url.path = '/'
8
11
  @bucket = BFS.resolve(url)
9
- @path = BFS.norm_path(url.path)
10
12
  end
11
13
 
12
14
  # Info returns the blob info
data/lib/bfs/bucket/fs.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'bfs'
2
- require 'cgi'
3
2
  require 'fileutils'
4
3
  require 'pathname'
5
4
 
@@ -9,31 +8,31 @@ module BFS
9
8
  class FS < Abstract
10
9
  def initialize(root, _opts={})
11
10
  @root = Pathname.new(root.to_s)
12
- @prefix = "#{@root}/"
11
+ @prefix = "#{@root.to_s.chomp('/')}/"
13
12
  end
14
13
 
15
14
  # Lists the contents of a bucket using a glob pattern
16
15
  def ls(pattern='**/*', _opts={})
17
16
  Pathname.glob(@root.join(pattern)).select(&:file?).map do |name|
18
- name.to_s.sub(@prefix, '')
17
+ trim_prefix(name.to_s)
19
18
  end
20
19
  end
21
20
 
22
21
  # Info returns the info for a single file
23
22
  def info(path, _opts={})
24
- name = @root.join(norm_path(path))
25
- path = name.to_s.sub(@prefix, '')
26
- BFS::FileInfo.new(path, name.size, name.mtime)
23
+ full = @root.join(norm_path(path))
24
+ path = trim_prefix(full.to_s)
25
+ BFS::FileInfo.new(path, full.size, full.mtime)
27
26
  rescue Errno::ENOENT
28
27
  raise BFS::FileNotFound, path
29
28
  end
30
29
 
31
30
  # Creates a new file and opens it for writing
32
31
  def create(path, _opts={}, &block)
33
- name = @root.join(norm_path(path))
34
- FileUtils.mkdir_p(name.dirname.to_s)
32
+ full = @root.join(norm_path(path))
33
+ FileUtils.mkdir_p(full.dirname.to_s)
35
34
 
36
- temp = BFS::TempWriter.new(name) {|t| FileUtils.mv t, name.to_s }
35
+ temp = BFS::TempWriter.new(full) {|t| FileUtils.mv t, full.to_s }
37
36
  return temp unless block
38
37
 
39
38
  begin
@@ -46,50 +45,49 @@ module BFS
46
45
  # Opens an existing file for reading
47
46
  def open(path, opts={}, &block)
48
47
  path = norm_path(path)
49
- name = @root.join(path)
50
- name.open('r', opts, &block)
48
+ full = @root.join(path)
49
+ full.open('r', opts, &block)
51
50
  rescue Errno::ENOENT
52
51
  raise BFS::FileNotFound, path
53
52
  end
54
53
 
55
54
  # Deletes a file.
56
55
  def rm(path, _opts={})
57
- name = @root.join(norm_path(path))
58
- FileUtils.rm_f name.to_s
56
+ full = @root.join(norm_path(path))
57
+ FileUtils.rm_f full.to_s
59
58
  end
60
59
 
61
60
  # Copies a file.
62
61
  def cp(src, dst, _opts={})
63
- src = norm_path(src)
64
- dst = norm_path(dst)
65
- FileUtils.cp @root.join(src).to_s, @root.join(dst).to_s
62
+ full_src = @root.join(norm_path(src))
63
+ full_dst = @root.join(norm_path(dst))
64
+ FileUtils.mkdir_p full_dst.dirname.to_s
65
+ FileUtils.cp full_src.to_s, full_dst.to_s
66
66
  rescue Errno::ENOENT
67
- raise BFS::FileNotFound, src
67
+ raise BFS::FileNotFound, norm_path(src)
68
68
  end
69
69
 
70
70
  # Moves a file.
71
71
  def mv(src, dst, _opts={})
72
- src = norm_path(src)
73
- dst = norm_path(dst)
74
- FileUtils.mv @root.join(src).to_s, @root.join(dst).to_s
72
+ full_src = @root.join(norm_path(src))
73
+ full_dst = @root.join(norm_path(dst))
74
+ FileUtils.mkdir_p full_dst.dirname.to_s
75
+ FileUtils.mv full_src.to_s, full_dst.to_s
75
76
  rescue Errno::ENOENT
76
- raise BFS::FileNotFound, src
77
+ raise BFS::FileNotFound, norm_path(src)
78
+ end
79
+
80
+ private
81
+
82
+ def trim_prefix(path)
83
+ path.slice!(0, @prefix.size) if path.slice(0, @prefix.size) == @prefix
84
+ path
77
85
  end
78
86
  end
79
87
  end
80
88
  end
81
89
 
82
90
  BFS.register('file') do |url|
83
- params = CGI.parse(url.query.to_s)
84
-
85
91
  parts = [url.host, url.path].compact
86
- root = case params.key?('scope') && params['scope'].first
87
- when 'root'
88
- '/'
89
- when 'dir'
90
- File.dirname(File.join(*parts))
91
- else
92
- File.join(*parts)
93
- end
94
- BFS::Bucket::FS.new root
92
+ BFS::Bucket::FS.new File.join(*parts)
95
93
  end
@@ -1,27 +1,64 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe BFS::Blob do
4
- let(:bucket) { BFS::Bucket::InMem.new }
5
- before { allow(BFS).to receive(:resolve).and_return(bucket) }
6
- subject { described_class.new('memtest://bucket/path/to/file.txt') }
4
+ describe 'default' do
5
+ let(:bucket) { BFS::Bucket::InMem.new }
6
+ before { allow(BFS).to receive(:resolve).and_return(bucket) }
7
+ subject { described_class.new('memtest://bucket/path/to/file.txt') }
7
8
 
8
- it 'should move' do
9
- expect(subject.path).to eq('path/to/file.txt')
10
- expect { subject.mv('/to/other/path.txt') }.to raise_error(BFS::FileNotFound)
9
+ it 'should move' do
10
+ expect(subject.path).to eq('path/to/file.txt')
11
+ expect { subject.mv('/to/other/path.txt') }.to raise_error(BFS::FileNotFound)
11
12
 
12
- subject.write('TESTDATA')
13
- subject.mv('/to/other/path.txt')
14
- expect(subject.path).to eq('to/other/path.txt')
13
+ subject.write('TESTDATA')
14
+ subject.mv('/to/other/path.txt')
15
+ expect(subject.path).to eq('to/other/path.txt')
16
+ end
17
+
18
+ it 'should write/read' do
19
+ expect { subject.read }.to raise_error(BFS::FileNotFound)
20
+ subject.write('TESTDATA')
21
+
22
+ info = subject.info
23
+ expect(info).to eq(BFS::FileInfo.new('path/to/file.txt', 8, info.mtime))
24
+ expect(info.mtime).to be_within(1).of(Time.now)
25
+
26
+ expect(subject.read).to eq('TESTDATA')
27
+ end
15
28
  end
16
29
 
17
- it 'should write/read' do
18
- expect { subject.read }.to raise_error(BFS::FileNotFound)
19
- subject.write('TESTDATA')
30
+ describe 'file system' do
31
+ let(:tmpdir) { Dir.mktmpdir }
32
+ let(:path) { "#{tmpdir}/path/to/file.txt".sub('/', '') }
33
+ after { FileUtils.rm_rf tmpdir }
34
+ subject { described_class.new("file:///#{path}") }
35
+
36
+ it 'should move' do
37
+ expect(subject.path).to eq(path)
38
+ expect { subject.mv("#{tmpdir}/to/other/path.txt") }.to raise_error(BFS::FileNotFound)
39
+
40
+ subject.write('TESTDATA')
41
+ subject.mv("#{tmpdir}/to/other/path.txt")
42
+
43
+ expect(subject.path).to eq("#{tmpdir}/to/other/path.txt".sub('/', ''))
44
+ expect(Pathname.glob("#{tmpdir}/**/*").select(&:file?).map(&:to_s)).to eq [
45
+ "#{tmpdir}/to/other/path.txt",
46
+ ]
47
+ end
48
+
49
+ it 'should write/read' do
50
+ expect { subject.read }.to raise_error(BFS::FileNotFound)
51
+
52
+ subject.write('TESTDATA')
53
+ expect(subject.read).to eq('TESTDATA')
20
54
 
21
- info = subject.info
22
- expect(info).to eq(BFS::FileInfo.new('path/to/file.txt', 8, info.mtime))
23
- expect(info.mtime).to be_within(1).of(Time.now)
55
+ info = subject.info
56
+ expect(info).to eq(BFS::FileInfo.new(path, 8, info.mtime))
57
+ expect(info.mtime).to be_within(1).of(Time.now)
24
58
 
25
- expect(subject.read).to eq('TESTDATA')
59
+ expect(Pathname.glob("#{tmpdir}/**/*").select(&:file?).map(&:to_s)).to eq [
60
+ "#{tmpdir}/path/to/file.txt",
61
+ ]
62
+ end
26
63
  end
27
64
  end
@@ -13,13 +13,5 @@ RSpec.describe BFS::Bucket::FS do
13
13
  bucket = BFS.resolve("file://#{tmpdir}")
14
14
  expect(bucket).to be_instance_of(described_class)
15
15
  expect(bucket.ls).to eq(['test.txt'])
16
-
17
- bucket = BFS.resolve("file://#{tmpdir}/test.txt?scope=dir")
18
- expect(bucket).to be_instance_of(described_class)
19
- expect(bucket.ls).to eq(['test.txt'])
20
-
21
- bucket = BFS.resolve("file://#{tmpdir}/test.txt?scope=root")
22
- expect(bucket).to be_instance_of(described_class)
23
- expect(bucket.instance_variable_get(:@root).to_s).to eq('/')
24
16
  end
25
17
  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.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitrij Denissenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-17 00:00:00.000000000 Z
11
+ date: 2018-10-18 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Minimalist abstraction for bucket storage
14
14
  email: dimitrij@blacksquaremedia.com