bfs 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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