vfs 0.3.15 → 0.4.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.
@@ -1,26 +1,25 @@
1
1
  module Vfs
2
2
  class Entry
3
- attr_reader :storage, :path, :path_cache
3
+ attr_reader :driver, :path, :path_cache
4
4
 
5
5
  def initialize *args
6
6
  if args.size == 1 and args.first.is_a? Entry
7
7
  entry = args.first
8
8
  @path_cache = entry.path_cache
9
- @storage, @path = entry.storage, entry.path
9
+ @driver, @path = entry.driver, entry.path
10
10
  else
11
- storage, path = *args
11
+ driver, path = *args
12
12
  @path_cache = Path.new path
13
- @storage, @path = storage, path_cache.to_s
13
+ @driver, @path = driver, path_cache.to_s
14
14
  end
15
- raise "storage not defined!" unless self.storage
15
+ raise "driver not defined!" unless self.driver
16
16
  end
17
17
 
18
-
19
18
  #
20
19
  # Navigation
21
20
  #
22
21
  def parent
23
- Dir.new(storage, path_cache + '..')
22
+ Dir.new(driver, path_cache + '..')
24
23
  end
25
24
 
26
25
 
@@ -30,7 +29,7 @@ module Vfs
30
29
  def dir path = nil
31
30
  if path
32
31
  new_path = path_cache + path
33
- Dir.new storage, new_path
32
+ Dir.new driver, new_path
34
33
  else
35
34
  Dir.new self
36
35
  end
@@ -40,7 +39,7 @@ module Vfs
40
39
  def file path = nil
41
40
  if path
42
41
  new_path = path_cache + path
43
- File.new storage, new_path
42
+ File.new driver, new_path
44
43
  else
45
44
  File.new self
46
45
  end
@@ -49,10 +48,9 @@ module Vfs
49
48
 
50
49
  def entry path = nil
51
50
  entry = if path
52
-
53
51
  new_path = path_cache + path
54
52
  klass = new_path.probably_dir? ? Dir : UniversalEntry
55
- entry = klass.new storage, new_path
53
+ klass.new driver, new_path
56
54
  else
57
55
  UniversalEntry.new self
58
56
  end
@@ -65,7 +63,7 @@ module Vfs
65
63
  # Attributes
66
64
  #
67
65
  def get attr_name = nil
68
- attrs = storage.open{|fs| fs.attributes(path)}
66
+ attrs = driver.open{driver.attributes(path)}
69
67
  (attr_name and attrs) ? attrs[attr_name] : attrs
70
68
  end
71
69
 
@@ -88,19 +86,19 @@ module Vfs
88
86
  end
89
87
 
90
88
  def tmp &block
91
- storage.open do |fs|
89
+ driver.open do
92
90
  if block
93
- fs.tmp do |path|
94
- block.call Dir.new(storage, path)
91
+ driver.tmp do |path|
92
+ block.call Dir.new(driver, path)
95
93
  end
96
94
  else
97
- Dir.new storage, fs.tmp
95
+ Dir.new driver, driver.tmp
98
96
  end
99
97
  end
100
98
  end
101
99
 
102
100
  def local?
103
- storage.local?
101
+ driver.local?
104
102
  end
105
103
 
106
104
 
@@ -108,22 +106,42 @@ module Vfs
108
106
  # Utils
109
107
  #
110
108
  def inspect
111
- "#{storage}#{':' unless storage.to_s.empty?}#{path}"
109
+ "#{driver}#{':' unless driver.to_s.empty?}#{path}"
112
110
  end
113
111
  alias_method :to_s, :inspect
114
112
 
115
113
  def == other
116
114
  return false unless other.is_a? Entry
117
- storage == other.storage and path == other.path
115
+ driver == other.driver and path == other.path
118
116
  end
119
117
 
120
118
  def hash
121
- storage.hash + path.hash
119
+ driver.hash + path.hash
122
120
  end
123
121
 
124
122
  def eql? other
125
123
  return false unless other.class == self.class
126
- storage.eql?(other.storage) and path.eql?(other.path)
124
+ driver.eql?(other.driver) and path.eql?(other.path)
127
125
  end
126
+
127
+ protected
128
+ def destroy_entry first = :file, second = :dir
129
+ driver.open do
130
+ begin
131
+ driver.send :"delete_#{first}", path
132
+ rescue StandardError => e
133
+ attrs = get
134
+ if attrs and attrs[first]
135
+ # some unknown error
136
+ raise e
137
+ elsif attrs and attrs[second]
138
+ driver.send :"delete_#{second}", path
139
+ else
140
+ # do nothing, entry already not exist
141
+ end
142
+ end
143
+ end
144
+ self
145
+ end
128
146
  end
129
147
  end
@@ -11,13 +11,13 @@ module Vfs
11
11
  #
12
12
  def read options = {}, &block
13
13
  options[:bang] = true unless options.include? :bang
14
- storage.open do |fs|
14
+ driver.open do
15
15
  begin
16
16
  if block
17
- fs.read_file path, &block
17
+ driver.read_file path, &block
18
18
  else
19
19
  data = ""
20
- fs.read_file(path){|buff| data << buff}
20
+ driver.read_file(path){|buff| data << buff}
21
21
  data
22
22
  end
23
23
  rescue StandardError => e
@@ -39,18 +39,14 @@ module Vfs
39
39
  end
40
40
  end
41
41
 
42
- def content options = {}
43
- read options
44
- end
42
+ # def content options = {}
43
+ # read options
44
+ # end
45
45
 
46
46
  def create options = {}
47
47
  write '', options
48
48
  self
49
49
  end
50
- def create! options = {}
51
- options[:override] = true
52
- create options
53
- end
54
50
 
55
51
  def write *args, &block
56
52
  if block
@@ -61,35 +57,24 @@ module Vfs
61
57
  end
62
58
  raise "can't do :override and :append at the same time!" if options[:override] and options[:append]
63
59
 
64
- storage.open do |fs|
65
- # TODO2 Performance lost, extra call to check file existence
66
- # We need to check if the file exist before writing to it, otherwise it's
67
- # impossible to distinguish if the StandardError caused by the 'already exist' error or
68
- # some other error.
69
- entry = self.entry
70
- if entry.exist?
71
- if options[:override]
72
- entry.destroy
73
- else
74
- raise Error, "entry #{self} already exist!"
75
- end
76
- end
77
-
60
+ driver.open do
78
61
  try = 0
79
62
  begin
80
63
  try += 1
81
64
  if block
82
- fs.write_file(path, options[:append], &block)
65
+ driver.write_file(path, options[:append], &block)
83
66
  else
84
- fs.write_file(path, options[:append]){|writer| writer.write data}
67
+ driver.write_file(path, options[:append]){|writer| writer.write data}
85
68
  end
86
69
  rescue StandardError => error
87
70
  parent = self.parent
88
- if parent.exist?
89
- # some unknown error
90
- raise error
91
- else
71
+ if entry.exist?
72
+ entry.destroy
73
+ elsif !parent.exist?
92
74
  parent.create(options)
75
+ else
76
+ # unknown error
77
+ raise error
93
78
  end
94
79
 
95
80
  try < 2 ? retry : raise(error)
@@ -97,11 +82,6 @@ module Vfs
97
82
  end
98
83
  self
99
84
  end
100
- def write! *args, &block
101
- args << {} unless args.last.is_a? Hash
102
- args.last[:override] = true
103
- write *args, &block
104
- end
105
85
 
106
86
  def append *args, &block
107
87
  options = (args.last.is_a?(Hash) && args.pop) || {}
@@ -110,37 +90,12 @@ module Vfs
110
90
  end
111
91
 
112
92
  def update options = {}, &block
113
- options[:override] = true
114
93
  data = read options
115
94
  write block.call(data), options
116
95
  end
117
96
 
118
- def destroy options = {}
119
- storage.open do |fs|
120
- begin
121
- fs.delete_file path
122
- self
123
- rescue StandardError => e
124
- attrs = get
125
- if attrs and attrs[:dir]
126
- if options[:force]
127
- dir.destroy
128
- else
129
- raise Error, "can't destroy Dir #{dir} (you are trying to destroy it as if it's a File)"
130
- end
131
- elsif attrs and attrs[:file]
132
- # unknown internal error
133
- raise e
134
- else
135
- # do nothing, file already not exist
136
- end
137
- end
138
- end
139
- self
140
- end
141
- def destroy! options = {}
142
- options[:force] = true
143
- destroy options
97
+ def destroy
98
+ destroy_entry
144
99
  end
145
100
 
146
101
 
@@ -166,20 +121,12 @@ module Vfs
166
121
 
167
122
  target
168
123
  end
169
- def copy_to! to, options = {}
170
- options[:override] = true
171
- copy_to to, options
172
- end
173
124
 
174
- def move_to to, options = {}
175
- copy_to to, options
176
- destroy options
125
+ def move_to to
126
+ copy_to to
127
+ destroy
177
128
  to
178
129
  end
179
- def move_to! to, options = {}
180
- options[:override] = true
181
- move_to to, options
182
- end
183
130
 
184
131
 
185
132
  #
@@ -8,17 +8,17 @@ module Vfs
8
8
  end
9
9
 
10
10
 
11
+ def copy_to to, options = {}
12
+ from = file? ? to_file : to_dir
13
+ from.copy_to to, options
14
+ end
15
+
16
+
11
17
  #
12
18
  # CRUD
13
19
  #
14
- def destroy options = {}
15
- storage.open do |fs|
16
- attrs = get
17
- fs.delete_dir path if attrs and attrs[:dir]
18
- fs.delete_file path if attrs and attrs[:file]
19
- end
20
- self
20
+ def destroy
21
+ destroy_entry
21
22
  end
22
- alias_method :destroy!, :destroy
23
23
  end
24
24
  end
@@ -0,0 +1,30 @@
1
+ class String
2
+ def to_entry_on driver = nil
3
+ path = self
4
+ driver ||= Vfs.default_driver
5
+
6
+ path = "./#{path}" unless path =~ /^[\/\.\~]/
7
+ Vfs::Entry.new(driver, path).entry
8
+ end
9
+ alias_method :to_entry, :to_entry_on
10
+
11
+ def to_file_on driver = nil
12
+ to_entry_on(driver).file
13
+ end
14
+ alias_method :to_file, :to_file_on
15
+
16
+ def to_dir_on driver = nil
17
+ to_entry_on(driver).dir
18
+ end
19
+ alias_method :to_dir, :to_dir_on
20
+ end
21
+
22
+ class File
23
+ def to_entry
24
+ path.to_entry
25
+ end
26
+
27
+ def to_file
28
+ path.to_file
29
+ end
30
+ end
data/lib/vfs/vfs.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Vfs
2
2
  class << self
3
- def default_storage
4
- ::Vfs::Storages::Local.new
3
+ def default_driver
4
+ ::Vfs::Drivers::Local.new
5
5
  end
6
6
 
7
7
  def to_entry
data/readme.md CHANGED
@@ -51,7 +51,7 @@ projects['cool_app'].copy_to deploy_dir
51
51
 
52
52
  dbc = deploy_dir.file('config/database.yml') # <= the 'config' dir not exist yet
53
53
  dbc.write("user: root\npassword: secret") # <= now the 'database.yml' and parent 'config' has been created
54
- dbc.content =~ /database/ # => false, we forgot to add the database
54
+ dbc.read =~ /database/ # => false, we forgot to add the database
55
55
  dbc.append("\ndatabase: mysql") # let's do it
56
56
 
57
57
  dbc.update do |content| # and add host info
@@ -1,29 +1,30 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'Container' do
4
- with_test_fs
4
+ with_test_dir
5
5
 
6
6
  it "should threat paths as UniversalEntry except it ends with '/'" do
7
- test_fs.should_receive(:entry).with('tmp/a/b')
8
- test_fs['tmp/a/b']
7
+ test_dir.should_receive(:entry).with('tmp/a/b')
8
+ test_dir['tmp/a/b']
9
9
 
10
- test_fs.should_receive(:dir).with('tmp/a/b')
11
- test_fs['tmp/a/b/']
10
+ test_dir.should_receive(:dir).with('tmp/a/b')
11
+ test_dir['tmp/a/b/']
12
12
  end
13
13
 
14
14
  it '/' do
15
- test_fs[:some_path].should == test_fs / :some_path
16
- test_fs[:some_path][:another_path].should == test_fs / :some_path / :another_path
15
+ test_dir[:some_path].should == test_dir / :some_path
16
+ test_dir[:some_path][:another_path].should == test_dir / :some_path / :another_path
17
17
  end
18
18
 
19
19
  it "UniversalEntry should be wrapped inside of proxy, Dir and File should not" do
20
- -> {test_fs.dir.proxy?}.should raise_error(NoMethodError)
21
- -> {test_fs.file.proxy?}.should raise_error(NoMethodError)
22
- test_fs.entry.proxy?.should be_true
20
+ -> {test_dir.dir.proxy?}.should raise_error(NoMethodError)
21
+ -> {test_dir.file.proxy?}.should raise_error(NoMethodError)
22
+ test_dir.entry.proxy?.should be_true
23
23
  end
24
24
 
25
25
  it "sometimes it also should inexplicitly guess that path is a Dir instead of UniversalEntry (but still wrap it inside of Proxy)" do
26
- dir = test_fs['tmp/a/..']
26
+
27
+ dir = test_dir['tmp/a/..']
27
28
  dir.proxy?.should be_true
28
29
  dir.should be_a(Vfs::Dir)
29
30
  end
data/spec/dir_spec.rb CHANGED
@@ -1,10 +1,10 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'Dir' do
4
- with_test_fs
4
+ with_test_dir
5
5
 
6
6
  before do
7
- @path = test_fs['a/b/c']
7
+ @path = test_dir['a/b/c']
8
8
  end
9
9
 
10
10
  describe 'existence' do
@@ -13,7 +13,7 @@ describe 'Dir' do
13
13
  @path.file.create
14
14
  @path.should be_file
15
15
  @path.dir.should_not exist
16
- @path.dir.create!
16
+ @path.dir.create
17
17
  @path.should be_dir
18
18
  @path.dir.should exist
19
19
  end
@@ -27,7 +27,6 @@ describe 'Dir' do
27
27
  describe 'create' do
28
28
  it 'should be chainable' do
29
29
  @path.dir.create.should == @path
30
- @path.dir.create!.should == @path
31
30
  end
32
31
 
33
32
  it 'should create parent dirs if not exists' do
@@ -41,27 +40,29 @@ describe 'Dir' do
41
40
  @path.dir.create
42
41
  end
43
42
 
44
- it 'should override existing file if override specified' do
43
+ it 'should override existing file' do
45
44
  @path.file.create
46
45
  @path.should be_file
47
- -> {@path.dir.create}.should raise_error(Vfs::Error, /exist/)
48
- @path.dir.create!
46
+ @path.dir.create
49
47
  @path.should be_dir
50
48
  end
51
49
 
52
- it 'should override existing dir if override specified' do
53
- @path.dir.create
54
- @path.should be_dir
55
- @path.dir.create!
56
- @path.should be_dir
50
+ it 'should not override existing dir with content' do
51
+ dir = @path.dir
52
+ dir.create
53
+ file = dir.file :file
54
+ file.create
55
+ file.should exist
56
+
57
+ dir.create
58
+ file.should exist
57
59
  end
58
60
  end
59
61
 
60
62
  describe 'destroying' do
61
- it "should raise error if it's trying to destroy a file (unless force specified)" do
63
+ it "should destroy a file" do
62
64
  @path.file.create
63
- -> {@path.dir.destroy}.should raise_error(Vfs::Error, /can't destroy File/)
64
- @path.dir.destroy!
65
+ @path.dir.destroy
65
66
  @path.entry.should_not exist
66
67
  end
67
68
 
@@ -72,9 +73,9 @@ describe 'Dir' do
72
73
  it 'should destroy recursivelly' do
73
74
  dir = @path.dir
74
75
  dir.create
75
- dir.file('file').write 'something'
76
- dir.dir('dir').create.tap do |dir|
77
- dir.file('file2').write 'something2'
76
+ dir.file(:file).write 'something'
77
+ dir.dir(:dir).create.tap do |dir|
78
+ dir.file(:file2).write 'something2'
78
79
  end
79
80
 
80
81
  dir.destroy
@@ -83,7 +84,6 @@ describe 'Dir' do
83
84
 
84
85
  it 'should be chainable' do
85
86
  @path.dir.destroy.should == @path
86
- @path.dir.destroy!.should == @path
87
87
  end
88
88
  end
89
89
 
@@ -97,10 +97,14 @@ describe 'Dir' do
97
97
  it 'entries' do
98
98
  -> {@path['non_existing'].entries}.should raise_error(Vfs::Error, /not exist/)
99
99
  @path['non_existing'].entries(bang: false).should == []
100
- @path.entries.to_set.should be_eql([@path.dir('dir'), @path.file('file')].to_set)
100
+ @path.entries.to_set.should be_eql([@path.entry('dir'), @path.entry('file')].to_set)
101
101
  list = []
102
102
  @path.entries{|e| list << e}
103
- list.to_set.should be_eql([@path.dir('dir'), @path.file('file')].to_set)
103
+ list.to_set.should be_eql([@path.entry('dir'), @path.entry('file')].to_set)
104
+ end
105
+
106
+ it 'entries with type' do
107
+ @path.entries(type: true).to_set.should be_eql([@path.dir('dir'), @path.file('file')].to_set)
104
108
  end
105
109
 
106
110
  it "glob search support" do
@@ -151,32 +155,28 @@ describe 'Dir' do
151
155
  end
152
156
 
153
157
  shared_examples_for 'copy_to behavior' do
154
- it 'should not copy to file (and overwrite if forced)' do
155
- -> {@from.copy_to @to.file}.should raise_error(/can't copy Dir to File/)
156
-
157
- @from.copy_to! @to.file
158
+ it 'should copy to file and overwrite it' do
159
+ @from.copy_to @to.file
158
160
  @to['file'].read.should == 'something'
159
161
  end
160
162
 
161
- it 'should not override files (and override if forced)' do
163
+ it 'should override files' do
162
164
  @from.copy_to @to
163
- -> {@from.copy_to @to}.should raise_error(/already exist/)
164
165
 
165
- @from['dir/file2'].write! 'another'
166
- @from.copy_to! @to
166
+ @from['dir/file2'].write 'another'
167
+ @from.copy_to @to
167
168
  @to['dir/file2'].read.should == 'another'
168
169
  end
169
170
 
170
- it 'should copy to UniversalEntry (and overwrite if forced)' do
171
+ it 'should copy to UniversalEntry (and overwrite)' do
171
172
  @from.copy_to @to.entry
172
- -> {@from.copy_to @to.entry}.should raise_error(/already exist/)
173
173
 
174
- @from.copy_to! @to.entry
174
+ @from.copy_to @to.entry
175
175
  @to['file'].read.should == 'something'
176
176
  end
177
177
 
178
178
  it "shouldn't delete existing content of directory" do
179
- @to.dir.create!
179
+ @to.dir.create
180
180
  @to.file('existing_file').write 'existing_content'
181
181
  @to.dir('existing_dir').create
182
182
  @to.file('dir/existing_file2').write 'existing_content2'
@@ -193,16 +193,21 @@ describe 'Dir' do
193
193
 
194
194
  it 'should be chainable' do
195
195
  @from.copy_to(@to).should == @to
196
- @from.copy_to!(@to).should == @to
197
196
  end
198
197
 
199
198
  it "should override without deleting other files" do
200
199
  @from.copy_to(@to).should == @to
201
200
  @to.file('other_file').write 'other'
202
201
 
203
- @from.copy_to!(@to).should == @to
202
+ @from.copy_to(@to).should == @to
204
203
  @to.file('other_file').read.should == 'other'
205
204
  end
205
+
206
+ it "should raise error if try to copy file as dir" do
207
+ dir = @from.dir 'file'
208
+ dir.file?.should be_true
209
+ -> {dir.copy_to @to}.should raise_error(Vfs::Error)
210
+ end
206
211
  end
207
212
 
208
213
  describe 'general copy' do
@@ -212,7 +217,7 @@ describe 'Dir' do
212
217
  # prevenging usage of :efficient_dir_copy
213
218
  # Vfs::Dir.dont_use_efficient_dir_copy = true
214
219
 
215
- @to = test_fs['to']
220
+ @to = test_dir['to']
216
221
  end
217
222
  # after do
218
223
  # Vfs::Dir.dont_use_efficient_dir_copy = false
@@ -223,7 +228,7 @@ describe 'Dir' do
223
228
  # it_should_behave_like 'copy_to behavior'
224
229
  #
225
230
  # before do
226
- # @to = test_fs['to']
231
+ # @to = test_dir['to']
227
232
  # end
228
233
  # end
229
234
  end
@@ -231,19 +236,14 @@ describe 'Dir' do
231
236
  describe 'moving' do
232
237
  it 'move_to' do
233
238
  from, to = @path.file('from'), @path.file('to')
234
- from.should_receive(:copy_to).with(to, {})
235
- from.should_receive(:destroy).with({})
239
+ from.should_receive(:copy_to).with(to)
240
+ from.should_receive(:destroy).with()
236
241
  from.move_to to
237
-
238
- from.should_receive(:move_to).with(to, override: true)
239
- from.move_to! to
240
242
  end
241
243
 
242
244
  it 'should be chainable' do
243
245
  from, to = @path.dir('from').create, @path.dir('to')
244
246
  from.move_to(to).should == to
245
- from.create
246
- from.move_to!(to).should == to
247
247
  end
248
248
  end
249
249
  end