rubypath 0.3.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,29 +0,0 @@
1
- require 'rubypath/version'
2
- require 'tmpdir'
3
-
4
- #
5
- #
6
- #
7
- class Path
8
- require 'rubypath/identity'
9
- require 'rubypath/construction'
10
- require 'rubypath/comparison'
11
- require 'rubypath/extensions'
12
-
13
- require 'rubypath/path_operations'
14
- require 'rubypath/path_predicates'
15
- require 'rubypath/file_operations'
16
- require 'rubypath/file_predicates'
17
- require 'rubypath/dir_operations'
18
- require 'rubypath/io_operations'
19
-
20
- require 'rubypath/mock'
21
- require 'rubypath/backend'
22
-
23
- end
24
-
25
- module Kernel
26
- def Path(*args)
27
- Path.new *args
28
- end
29
- end
@@ -1,92 +0,0 @@
1
- class Path
2
- class Backend
3
- class << self
4
- def instance
5
- @instance ||= new
6
- end
7
-
8
- def delegate(mth)
9
- define_method mth do |*args|
10
- backend.send mth, *args
11
- end
12
- end
13
-
14
- def mock(*args, &block)
15
- self.instance.mock(*args, &block)
16
- end
17
- end
18
-
19
- attr_accessor :backend
20
- def initialize
21
- self.backend = Backend::Sys.new
22
- end
23
-
24
- def mock(opts = {}, &block)
25
- if opts[:root]
26
- # Use real file system scoped to given directory (chroot like)
27
- if opts[:root] == :tmp
28
- ::Dir.mktmpdir('rubypath') do |path|
29
- use_backend Backend::Sys.new(path), &block
30
- end
31
- else
32
- use_backend Backend::Sys.new(opts[:root]), &block
33
- end
34
- else
35
- # Use mock FS
36
- use_backend Backend::Mock.new, &block
37
- end
38
- end
39
-
40
- def use_backend(be)
41
- old_backend, self.backend = backend, be
42
- yield
43
- backend.quit if backend.respond_to? :quit
44
- self.backend = old_backend
45
- end
46
-
47
- delegate :expand_path
48
- delegate :getwd
49
- delegate :exists?
50
- delegate :mkdir
51
- delegate :mkpath
52
- delegate :directory?
53
- delegate :file?
54
- delegate :touch
55
- delegate :write
56
- delegate :read
57
- delegate :mtime
58
- delegate :mtime=
59
- delegate :entries
60
- delegate :glob
61
- delegate :atime
62
- delegate :atime=
63
- delegate :get_umask
64
- delegate :set_umask
65
- delegate :mode
66
- delegate :chmod
67
- delegate :unlink
68
- delegate :rmtree
69
- delegate :rmtree!
70
- delegate :safe_rmtree
71
- delegate :safe_rmtree!
72
- end
73
-
74
- private
75
-
76
- def invoke_backend(mth, *args)
77
- args << self if args.empty?
78
- self.class.send :invoke_backend, mth, *args
79
- end
80
-
81
- class << self
82
-
83
- private
84
-
85
- def invoke_backend(mth, *args)
86
- Backend.instance.send mth, *args
87
- end
88
- end
89
-
90
- require 'rubypath/backend/mock'
91
- require 'rubypath/backend/sys'
92
- end
@@ -1,356 +0,0 @@
1
- class Path::Backend
2
-
3
- class Mock
4
- attr_reader :user, :homes
5
-
6
- # @!group Virtual File System Configuration
7
-
8
- # Set user that owns the current process.
9
- def current_user=(user)
10
- @user = user.to_s
11
- end
12
-
13
- # Define new home directories. Must be given as has a hash that is
14
- # interpreted as a user name to home directory mapping.
15
- attr_writer :homes
16
-
17
- # Set current working directory.
18
- attr_writer :cwd
19
-
20
- # @!group Internal Methods
21
-
22
- def initialize
23
- @user = 'root'
24
- @homes = {'root' => '/root'}
25
- @cwd = '/root'
26
- @umask = 0022
27
- end
28
-
29
- def home(user)
30
- homes.fetch(user){ raise ArgumentError.new "user #{user} doesn't exist" }
31
- end
32
-
33
- # @!group Backend Operations
34
-
35
- def expand_path(path, base = getwd)
36
- if %r{^~(?<name>[^/]*)(/(?<rest>.*))?$} =~ path
37
- ::File.expand_path rest.to_s, home(name.empty? ? user : name)
38
- else
39
- ::File.expand_path(path, base)
40
- end
41
- end
42
- alias_method :expand, :expand_path
43
-
44
- def getwd
45
- @cwd ||= '/'
46
- end
47
-
48
- def file?(path)
49
- lookup(path).is_a?(File)
50
- end
51
-
52
- def directory?(path)
53
- lookup(path).is_a?(Dir)
54
- end
55
-
56
- def exists?(path)
57
- lookup(path) ? true : false
58
- end
59
-
60
- def mkdir(path)
61
- return if path.to_s == '/'
62
-
63
- node = lookup_parent! path
64
- dir = node.lookup ::File.basename path
65
- unless dir.is_a?(Dir)
66
- if dir.nil?
67
- node.add Dir.new(self, ::File.basename(path))
68
- else
69
- raise ArgumentError.new \
70
- "Node #{dir.path} exists and is no directory."
71
- end
72
- end
73
- end
74
-
75
- def mkpath(path)
76
- path = expand_path(path)
77
- ::Pathname.new(path).descend do |p|
78
- mkdir(p.to_s)
79
- end
80
- end
81
-
82
- def touch(path)
83
- node = lookup_parent! path
84
- file = node.lookup ::File.basename path
85
- if file
86
- file.mtime = Time.now
87
- else
88
- node.add File.new(self, ::File.basename(path))
89
- end
90
- end
91
-
92
- def write(path, content, *args)
93
- node = lookup_parent! path
94
- file = node.lookup ::File.basename(path)
95
- unless file
96
- file = File.new self, ::File.basename(path)
97
- node.add file
98
- end
99
-
100
- case file
101
- when File
102
- if args.empty?
103
- file.content = content
104
- else
105
- offset = args[0].to_i
106
- file.content[offset, content.length] = content
107
- end
108
- file.mtime = Time.now
109
- when Dir
110
- raise Errno::EISDIR.new path
111
- else
112
- raise ArgumentError.new
113
- end
114
- end
115
-
116
- def mtime(path)
117
- lookup!(path).mtime
118
- end
119
-
120
- def mtime=(path, time)
121
- lookup!(path).mtime = time
122
- end
123
-
124
- def atime(path)
125
- lookup!(path).atime
126
- end
127
-
128
- def atime=(path, time)
129
- lookup!(path).atime = time
130
- end
131
-
132
- def read(path, *args)
133
- file = lookup_file!(path)
134
- file.atime = Time.now
135
- content = file.content
136
- if args[0]
137
- length = args[0].to_i
138
- offset = args[1] ? args[1].to_i : 0
139
- content = content.slice(offset, length)
140
- end
141
- content
142
- end
143
-
144
- def entries(path)
145
- node = lookup_dir! path
146
- node.children.map(&:name) + %w(. ..)
147
- end
148
-
149
- def glob(pattern, flags = 0, &block)
150
- root.all.select do |node|
151
- ::File.fnmatch pattern, node.path, (flags | ::File::FNM_PATHNAME)
152
- end
153
- end
154
-
155
- def get_umask
156
- @umask
157
- end
158
-
159
- def set_umask(mask)
160
- @umask = Integer(mask)
161
- end
162
-
163
- def mode(path)
164
- lookup!(path).mode
165
- end
166
-
167
- def unlink(path)
168
- node = lookup_parent!(path)
169
- file = node.lookup ::File.basename path
170
- case file
171
- when Dir
172
- raise Errno::EISDIR.new path
173
- when File
174
- node.children.delete(file)
175
- when nil
176
- raise Errno::ENOENT.new path
177
- else
178
- raise ArgumentError.new "Unknown node #{node.inspect} for #unlink."
179
- end
180
- end
181
-
182
- def rmtree(path)
183
- node = lookup path
184
- case node
185
- when Dir, File
186
- lookup_parent!(path).children.delete(node)
187
- when nil
188
- nil
189
- else
190
- raise ArgumentError.new "Unknown node #{node.inspect} for #rmtree."
191
- end
192
- end
193
- alias_method :safe_rmtree, :rmtree
194
-
195
- def rmtree!(path)
196
- node = lookup path
197
- case node
198
- when Dir, File
199
- lookup_parent!(path).children.delete(node)
200
- when nil
201
- raise Errno::ENOENT.new path
202
- else
203
- raise ArgumentError.new "Unknown node #{node.inspect} for #rmtree."
204
- end
205
- end
206
- alias_method :safe_rmtree!, :rmtree!
207
-
208
- # @!group Internal Virtual File System
209
-
210
- # Return root node.
211
- def root
212
- @root ||= Dir.new(self, '')
213
- end
214
-
215
- def to_lookup(path)
216
- path = expand path
217
- path.sub(/^\/+/, '')
218
- end
219
-
220
- def lookup(path)
221
- root.lookup to_lookup path
222
- end
223
-
224
- def lookup!(path)
225
- if (node = lookup(path))
226
- node
227
- else
228
- raise Errno::ENOENT.new path
229
- end
230
- end
231
-
232
- def lookup_file!(path)
233
- node = lookup! path
234
- case node
235
- when File
236
- node
237
- when Dir
238
- raise Errno::EISDIR.new path
239
- else
240
- raise ArgumentError.new "NOT A FILE: #{path}"
241
- end
242
- end
243
-
244
- def lookup_dir!(path)
245
- if (node = lookup!(path)).is_a?(Dir)
246
- node
247
- else
248
- raise Errno::ENOENT.new path
249
- end
250
- end
251
-
252
- def lookup_parent!(path)
253
- node = lookup ::File.dirname expand path
254
- if node
255
- node.is_a?(Dir) ? node : raise(Errno::ENOTDIR.new path)
256
- else
257
- raise Errno::ENOENT.new path
258
- end
259
- end
260
-
261
- #
262
- class Node
263
- attr_reader :sys, :name, :parent
264
- attr_accessor :mtime, :atime, :mode
265
-
266
- def initialize(backend, name, ops = {})
267
- @sys = backend
268
- @name = name
269
- @mtime = Time.now
270
- @atime = Time.now
271
- end
272
-
273
- def mtime=(time)
274
- if time.is_a?(Time)
275
- @mtime = time
276
- else
277
- raise "Not Time but `#{time.inspect}` of `#{time.class.name}` given."
278
- end
279
- end
280
-
281
- def lookup(path)
282
- raise NotImplementError.new 'Subclass responsibility.'
283
- end
284
-
285
- def added(parent)
286
- @parent = parent
287
- end
288
-
289
- def path
290
- parent ? "#{parent.path}/#{name}" : name
291
- end
292
- end
293
-
294
- #
295
- class Dir < Node
296
- def initialize(backend, name, opts = {})
297
- super
298
- self.mode = 0777 - backend.get_umask
299
- end
300
-
301
- def lookup(path)
302
- name, rest = path.to_s.split('/', 2).map(&:to_s)
303
-
304
- if name.nil?
305
- if rest.nil?
306
- self
307
- else
308
- lookup rest
309
- end
310
- else
311
- child = children.find{|c| c.name == name }
312
- if child
313
- rest.nil? ? child : child.lookup(rest)
314
- else
315
- nil
316
- end
317
- end
318
- end
319
-
320
- def add(node)
321
- if children.any?{|c| c.name == node.name }
322
- raise ArgumentError.new "Node #{path}/#{node.name} already exists."
323
- else
324
- children << node
325
- node.added self
326
- end
327
- end
328
-
329
- def all
330
- children.reduce([]) do |memo, child|
331
- memo << child
332
- memo += child.all if child.is_a?(Dir)
333
- memo
334
- end
335
- end
336
-
337
- def children
338
- @children ||= []
339
- end
340
- end
341
-
342
- #
343
- class File < Node
344
- attr_accessor :content
345
-
346
- def initialize(backend, name, opts = {})
347
- super
348
- self.mode = 0666 - backend.get_umask
349
- end
350
-
351
- def lookup(path)
352
- nil
353
- end
354
- end
355
- end
356
- end