vfs 0.3.8 → 0.3.9
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.
- data/lib/vfs/entries/dir.rb +17 -6
- data/lib/vfs/entries/file.rb +7 -1
- data/lib/vfs/path.rb +9 -9
- data/lib/vfs/storages/hash_fs.rb +4 -2
- data/lib/vfs/storages/local.rb +20 -7
- data/lib/vfs/storages/specification.rb +2 -2
- data/readme.md +13 -9
- data/spec/dir_spec.rb +3 -1
- data/spec/entry_spec.rb +2 -0
- data/spec/file_spec.rb +2 -0
- data/spec/path_spec.rb +6 -2
- metadata +2 -2
data/lib/vfs/entries/dir.rb
CHANGED
@@ -92,12 +92,17 @@ module Vfs
|
|
92
92
|
#
|
93
93
|
# Content
|
94
94
|
#
|
95
|
-
def entries
|
95
|
+
def entries *args, &block
|
96
|
+
raise "invalid arguments #{args.inspect}!" if args.size > 2
|
97
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
98
|
+
query = args.first
|
96
99
|
options[:bang] = true unless options.include? :bang
|
100
|
+
|
97
101
|
storage.open_fs do |fs|
|
98
102
|
begin
|
99
103
|
list = []
|
100
|
-
fs
|
104
|
+
# query option is optional and supported only for some storages (local fs for example)
|
105
|
+
fs.each_entry path, query do |name, type|
|
101
106
|
next if options[:filter] and options[:filter] != type
|
102
107
|
entry = if type == :dir
|
103
108
|
dir(name)
|
@@ -125,14 +130,20 @@ module Vfs
|
|
125
130
|
end
|
126
131
|
alias_method :each, :entries
|
127
132
|
|
128
|
-
def files
|
133
|
+
def files *args, &block
|
134
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
135
|
+
|
129
136
|
options[:filter] = :file
|
130
|
-
|
137
|
+
args << options
|
138
|
+
entries *args, &block
|
131
139
|
end
|
132
140
|
|
133
|
-
def dirs
|
141
|
+
def dirs *args, &block
|
142
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
143
|
+
|
134
144
|
options[:filter] = :dir
|
135
|
-
|
145
|
+
args << options
|
146
|
+
entries *args, &block
|
136
147
|
end
|
137
148
|
|
138
149
|
def include? name
|
data/lib/vfs/entries/file.rb
CHANGED
@@ -190,7 +190,13 @@ module Vfs
|
|
190
190
|
require 'tilt'
|
191
191
|
|
192
192
|
args.unshift Object.new if args.size == 1 and args.first.is_a?(Hash)
|
193
|
-
|
193
|
+
|
194
|
+
template = Tilt.new path
|
195
|
+
template.render *args
|
196
|
+
end
|
197
|
+
|
198
|
+
def size
|
199
|
+
get :size
|
194
200
|
end
|
195
201
|
|
196
202
|
def basename
|
data/lib/vfs/path.rb
CHANGED
@@ -44,22 +44,22 @@ module Vfs
|
|
44
44
|
|
45
45
|
class << self
|
46
46
|
def absolute? path
|
47
|
-
path =~ /^[
|
47
|
+
path =~ /^[\/~\/]|^\.$|^\.\//
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
def valid? path, forbid_relative = true, &block
|
51
51
|
result, err = if forbid_relative and !absolute?(path)
|
52
|
-
[false, "path must be started with '/',
|
53
|
-
elsif path =~
|
54
|
-
[false, "path can't be ended with '/', '
|
55
|
-
elsif path =~
|
52
|
+
[false, "path must be started with '/', or '.'"]
|
53
|
+
elsif path =~ /.+\/~$|.+\/$|\/\.$/
|
54
|
+
[false, "path can't be ended with '/', '/~', or '/.'"]
|
55
|
+
elsif path =~ /\/\/|\/~\/|\/\.\//
|
56
56
|
[false, "path can't include '/./', '/~/', '//' combinations!"]
|
57
|
-
elsif path =~ /.+[~]|\/\.\//
|
58
|
-
|
57
|
+
# elsif path =~ /.+[~]|\/\.\//
|
58
|
+
# [false, "'~', or '.' can be present only at the begining of string"]
|
59
59
|
else
|
60
60
|
[true, nil]
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
block.call err if block and !result and err
|
64
64
|
result
|
65
65
|
end
|
data/lib/vfs/storages/hash_fs.rb
CHANGED
@@ -98,7 +98,9 @@ module Vfs
|
|
98
98
|
# raise 'not supported'
|
99
99
|
# end
|
100
100
|
|
101
|
-
def each_entry path, &block
|
101
|
+
def each_entry path, query, &block
|
102
|
+
raise "hash_fs not support :each_entry with query!" if query
|
103
|
+
|
102
104
|
base, name = split_path path
|
103
105
|
assert cd(base)[name], :include?, :dir
|
104
106
|
cd(base)[name].each do |relative_name, content|
|
@@ -135,7 +137,7 @@ module Vfs
|
|
135
137
|
|
136
138
|
if cd(to_base).include? to_name
|
137
139
|
if cd(to_base)[to_name][:dir]
|
138
|
-
each_entry from_path do |name, type|
|
140
|
+
each_entry from_path, nil do |name, type|
|
139
141
|
if type == :dir
|
140
142
|
_efficient_dir_copy "#{from_path}/#{name}", "#{to_path}/#{name}", override
|
141
143
|
else
|
data/lib/vfs/storages/local.rb
CHANGED
@@ -23,6 +23,7 @@ module Vfs
|
|
23
23
|
# attributes special for file system
|
24
24
|
attrs[:created_at] = stat.ctime
|
25
25
|
attrs[:updated_at] = stat.mtime
|
26
|
+
attrs[:size] = stat.size
|
26
27
|
attrs
|
27
28
|
rescue Errno::ENOENT
|
28
29
|
{}
|
@@ -72,13 +73,25 @@ module Vfs
|
|
72
73
|
FileUtils.rm_r path
|
73
74
|
end
|
74
75
|
|
75
|
-
def each_entry path, &block
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
76
|
+
def each_entry path, query, &block
|
77
|
+
if query
|
78
|
+
path_with_trailing_slash = path == '/' ? path : "#{path}/"
|
79
|
+
::Dir["#{path_with_trailing_slash}#{query}"].each do |absolute_path|
|
80
|
+
relative_path = absolute_path.sub path_with_trailing_slash, ''
|
81
|
+
if ::File.directory? absolute_path
|
82
|
+
block.call relative_path, :dir
|
83
|
+
else
|
84
|
+
block.call relative_path, :file
|
85
|
+
end
|
86
|
+
end
|
87
|
+
else
|
88
|
+
::Dir.foreach path do |relative_name|
|
89
|
+
next if relative_name == '.' or relative_name == '..'
|
90
|
+
if ::File.directory? "#{path}/#{relative_name}"
|
91
|
+
block.call relative_name, :dir
|
92
|
+
else
|
93
|
+
block.call relative_name, :file
|
94
|
+
end
|
82
95
|
end
|
83
96
|
end
|
84
97
|
end
|
@@ -101,7 +101,7 @@ shared_examples_for 'vfs storage' do
|
|
101
101
|
it 'each' do
|
102
102
|
@storage.open_fs do |fs|
|
103
103
|
list = {}
|
104
|
-
fs.each_entry(@tmp_dir){|path, type| list[path] = type}
|
104
|
+
fs.each_entry(@tmp_dir, nil){|path, type| list[path] = type}
|
105
105
|
list.should be_empty
|
106
106
|
|
107
107
|
dir, file = "#{@tmp_dir}/dir", "#{@tmp_dir}/file"
|
@@ -109,7 +109,7 @@ shared_examples_for 'vfs storage' do
|
|
109
109
|
fs.write_file(file, false){|w| w.call 'something'}
|
110
110
|
|
111
111
|
list = {}
|
112
|
-
fs.each_entry(@tmp_dir){|path, type| list[path] = type}
|
112
|
+
fs.each_entry(@tmp_dir, nil){|path, type| list[path] = type}
|
113
113
|
list.should == {'dir' => :dir, 'file' => :file}
|
114
114
|
end
|
115
115
|
end
|
data/readme.md
CHANGED
@@ -107,26 +107,30 @@ is to provide 1-to-1 clone of underlying OS API, instead of provididing handy to
|
|
107
107
|
And if you want to use remote FS - things are getting even worse and more complicated (Net::SSH & Net::SFTP use a little
|
108
108
|
different API than local FS, and you has to remember all thouse little quirks).
|
109
109
|
|
110
|
-
##
|
110
|
+
## Roadmap
|
111
111
|
|
112
|
-
###
|
112
|
+
### some future
|
113
113
|
|
114
|
-
-
|
115
|
-
- File.append
|
116
|
-
- list of entries/files/dirs
|
117
|
-
- support for efficient copy for Local and SSH storages
|
114
|
+
- add storages: Hadoop DFS, MongoDB, Amazon S3
|
118
115
|
|
119
116
|
### v 0.2
|
120
117
|
|
118
|
+
- refactor specs with :fakefs
|
121
119
|
- remove :host from Vfs to Vos
|
122
120
|
- efficient (not copy/destroy) versions of move_to, rename
|
123
|
-
- glob search for directories: Dir['**/*.yml']
|
124
121
|
- access via attributes and helpers for unix chmod
|
125
122
|
- add storages: remote FS over HTTP.
|
126
123
|
|
127
|
-
|
124
|
+
Done:
|
128
125
|
|
129
|
-
-
|
126
|
+
- glob search for directories: Dir['**/*.yml']
|
127
|
+
|
128
|
+
### v 0.1 (all done)
|
129
|
+
|
130
|
+
- Vos: Dir.bash
|
131
|
+
- File.append
|
132
|
+
- list of entries/files/dirs
|
133
|
+
- support for efficient copy for Local and SSH storages
|
130
134
|
|
131
135
|
[vos]: http://github.com/alexeypetrushin/vos
|
132
136
|
[cluster_management]: http://github.com/alexeypetrushin/cluster_management
|
data/spec/dir_spec.rb
CHANGED
@@ -86,7 +86,7 @@ describe 'Dir' do
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
-
describe '
|
89
|
+
describe 'entries, files, dirs' do
|
90
90
|
before do
|
91
91
|
@path.dir('dir').create
|
92
92
|
@path.dir('dir/another_dir').create
|
@@ -102,6 +102,8 @@ describe 'Dir' do
|
|
102
102
|
list.to_set.should be_eql([@path.dir('dir'), @path.file('file')].to_set)
|
103
103
|
end
|
104
104
|
|
105
|
+
it "glob search support"
|
106
|
+
|
105
107
|
it 'should raise error if trying :entries on file' do
|
106
108
|
@path.file('some_file').create
|
107
109
|
-> {@path.dir('some_file').entries}.should raise_error(/File/)
|
data/spec/entry_spec.rb
CHANGED
data/spec/file_spec.rb
CHANGED
data/spec/path_spec.rb
CHANGED
@@ -12,7 +12,10 @@ describe "Path" do
|
|
12
12
|
/a/../c
|
13
13
|
/a/...
|
14
14
|
~/a
|
15
|
-
./a
|
15
|
+
./a
|
16
|
+
/~a
|
17
|
+
/a~b
|
18
|
+
/a.b~
|
16
19
|
).each{|path| Path.should be_valid(path)}
|
17
20
|
|
18
21
|
special = ['']
|
@@ -35,9 +38,10 @@ describe "Path" do
|
|
35
38
|
/a /a
|
36
39
|
~/a ~/a
|
37
40
|
./a ./a
|
38
|
-
/a/../c /c
|
41
|
+
/a/../c /c
|
39
42
|
/ /
|
40
43
|
~ ~
|
44
|
+
/a~/b /a~/b
|
41
45
|
. .
|
42
46
|
) + special).each_slice(2) do |path, normalized_path|
|
43
47
|
Path.normalize(path).should == normalized_path
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vfs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-08-03 00:00:00 +04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|