rubypath 0.3.2 → 1.0.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,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