tagen 0.1.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.
- data/.gitignore +2 -0
- data/.yardopts +5 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +24 -0
- data/README.md +60 -0
- data/Rakefile +9 -0
- data/docs/Architecture.md +17 -0
- data/docs/CoreExtensions.md +56 -0
- data/docs/ExtraExtensions.md +20 -0
- data/lib/tagen/audioinfo.rb +21 -0
- data/lib/tagen/cairo.rb +809 -0
- data/lib/tagen/core.rb +34 -0
- data/lib/tagen/core/array.rb +41 -0
- data/lib/tagen/core/array/extract_options.rb +40 -0
- data/lib/tagen/core/hash.rb +17 -0
- data/lib/tagen/core/io.rb +29 -0
- data/lib/tagen/core/kernel.rb +73 -0
- data/lib/tagen/core/marshal.rb +34 -0
- data/lib/tagen/core/module.rb +25 -0
- data/lib/tagen/core/numeric.rb +10 -0
- data/lib/tagen/core/object.rb +21 -0
- data/lib/tagen/core/pa.rb +187 -0
- data/lib/tagen/core/pa/cmd.rb +374 -0
- data/lib/tagen/core/pa/dir.rb +144 -0
- data/lib/tagen/core/pa/path.rb +190 -0
- data/lib/tagen/core/pa/state.rb +56 -0
- data/lib/tagen/core/process.rb +11 -0
- data/lib/tagen/core/re.rb +8 -0
- data/lib/tagen/core/string.rb +43 -0
- data/lib/tagen/core/string/pyformat.rb +322 -0
- data/lib/tagen/core/time.rb +8 -0
- data/lib/tagen/gdk_pixbuf2.rb +26 -0
- data/lib/tagen/gtk2.rb +122 -0
- data/lib/tagen/magick.rb +23 -0
- data/lib/tagen/ncurses.rb +245 -0
- data/lib/tagen/net/http.rb +34 -0
- data/lib/tagen/pathname.rb +8 -0
- data/lib/tagen/poppler.rb +47 -0
- data/lib/tagen/socket.rb +20 -0
- data/lib/tagen/tree.rb +75 -0
- data/lib/tagen/vim.rb +19 -0
- data/lib/tagen/xmpp4r.rb +1 -0
- data/lib/tagen/xmpp4r/roster.rb +20 -0
- data/spec/cairo_spec.rb +137 -0
- data/spec/core/pa/cmd_spec.rb +251 -0
- data/spec/core/pa/dir_spec.rb +59 -0
- data/spec/core/string/pyformat_spec.rb +86 -0
- data/spec/spec_helper.rb +0 -0
- data/tagen.gemspec +20 -0
- data/version.rb +7 -0
- metadata +117 -0
@@ -0,0 +1,374 @@
|
|
1
|
+
=begin
|
2
|
+
rm family
|
3
|
+
* rm _rm file only_
|
4
|
+
* rmdir _rm directory only_
|
5
|
+
* rm_r _rm recurive, both file and directory_
|
6
|
+
* rm_if _with condition, use rm_r_
|
7
|
+
=== Example
|
8
|
+
rm path # it's clear: remove a file
|
9
|
+
rmdir path # it's clear: remove a directory
|
10
|
+
=end
|
11
|
+
class Pa
|
12
|
+
module Cmd
|
13
|
+
|
14
|
+
# chroot
|
15
|
+
# @see {Dir.chroot}
|
16
|
+
#
|
17
|
+
# @param [String] path
|
18
|
+
# @return [nil]
|
19
|
+
def chroot(path) Dir.chroot(get(path)) end
|
20
|
+
|
21
|
+
# touch a blank file
|
22
|
+
#
|
23
|
+
# @overload touch(*paths, o={})
|
24
|
+
# @param [String] *paths
|
25
|
+
# @param [Hash] o option
|
26
|
+
# @option o [Fixnum,String] :mode
|
27
|
+
# @option o [Boolean] :mkdir auto mkdir if path contained directory not exists.
|
28
|
+
# @option o [Boolean] :force
|
29
|
+
# @return [nil]
|
30
|
+
def touch(*args) paths, o = args.extract_options; _touch(*paths, o) end
|
31
|
+
|
32
|
+
# touch force
|
33
|
+
# @see touch
|
34
|
+
#
|
35
|
+
# @overload touch_f(*paths, o={})
|
36
|
+
# @return [nil]
|
37
|
+
def touch_f(*args) paths, o = args.extract_options; o[:force]=true; _touch(*paths, o) end
|
38
|
+
|
39
|
+
def _touch(paths, o)
|
40
|
+
o[:mode] ||= 0644
|
41
|
+
paths.map!{|v|get(v)}
|
42
|
+
paths.each {|p|
|
43
|
+
if exists?(p)
|
44
|
+
o[:force] ? next : raise(Errno::EEXIST, "File exist -- #{p}")
|
45
|
+
end
|
46
|
+
|
47
|
+
if o[:mkdir]
|
48
|
+
mkdir(dirname(p))
|
49
|
+
end
|
50
|
+
|
51
|
+
if win32?
|
52
|
+
# win32 BUG. must f.write("") then file can be deleted.
|
53
|
+
File.open(p, "w"){|f| f.chmod(o[:mode]); f.write("")}
|
54
|
+
else
|
55
|
+
File.open(p, "w"){|f| f.chmod(o[:mode])}
|
56
|
+
end
|
57
|
+
}
|
58
|
+
end
|
59
|
+
private :_touch
|
60
|
+
|
61
|
+
# make a directory
|
62
|
+
#
|
63
|
+
# @overload mkdir(*paths, o={})
|
64
|
+
# @param [String] *paths
|
65
|
+
# @param [Hash] o option
|
66
|
+
# @option o [Fixnum] :mode
|
67
|
+
# @option o [Boolean] :force
|
68
|
+
# @return [nil]
|
69
|
+
def mkdir(*args) paths, o = args.extract_options; _mkdir(paths, o) end
|
70
|
+
|
71
|
+
# mkdir force
|
72
|
+
# @see mkdir
|
73
|
+
#
|
74
|
+
# @overload mkdir_f(*paths, o={})
|
75
|
+
# @return [nil]
|
76
|
+
def mkdir_f(*args) paths, o = args.extract_options; o[:force]=true; _mkdir(*paths, o) end
|
77
|
+
|
78
|
+
def _mkdir(paths, o)
|
79
|
+
o[:mode] ||= 0744
|
80
|
+
paths.map!{|v|get(v)}
|
81
|
+
paths.each {|p|
|
82
|
+
if File.exists?(p)
|
83
|
+
o[:force] ? next : raise(Errno::EEXIST, "File exist -- #{p}")
|
84
|
+
end
|
85
|
+
|
86
|
+
stack = []
|
87
|
+
until p == stack.last
|
88
|
+
break if File.exists?(p)
|
89
|
+
stack << p
|
90
|
+
p = File.dirname(p)
|
91
|
+
end
|
92
|
+
|
93
|
+
stack.reverse.each do |path|
|
94
|
+
Dir.mkdir(path)
|
95
|
+
File.chmod(o[:mode], path)
|
96
|
+
end
|
97
|
+
}
|
98
|
+
end
|
99
|
+
private :_mkdir
|
100
|
+
|
101
|
+
# make temp directory
|
102
|
+
#
|
103
|
+
# @param [Hash] o options
|
104
|
+
# @option o [Symbol] :prefix ("")
|
105
|
+
# @option o [Symbol] :suffix ("")
|
106
|
+
# @option o [Symbol] :tmpdir (ENV["TEMP"])
|
107
|
+
# @return [String] path
|
108
|
+
def mktmpdir(o={}, &blk)
|
109
|
+
p = _mktmpname(o)
|
110
|
+
File.mkdir(p)
|
111
|
+
begin blk.call(p) ensure Dir.delete(p) end if blk
|
112
|
+
p
|
113
|
+
end # def mktmpdir
|
114
|
+
|
115
|
+
def home(user=nil) Dir.home end
|
116
|
+
|
117
|
+
# make temp file
|
118
|
+
# @see mktmpdir
|
119
|
+
#
|
120
|
+
# @param [Hash] o options
|
121
|
+
# @return [String] path
|
122
|
+
def mktmpfile(o={}, &blk)
|
123
|
+
p = _mktmpname(o)
|
124
|
+
begin blk.call(p) ensure File.delete(p) end if blk
|
125
|
+
p
|
126
|
+
end # mktmpfile
|
127
|
+
|
128
|
+
def _mktmpname(o={})
|
129
|
+
# :prefix :suffix :tmpdir
|
130
|
+
# $$-(time*100_000).to_i.to_s(36)
|
131
|
+
# parse o
|
132
|
+
o[:dir] ||= ENV["TEMP"]
|
133
|
+
o[:prefix] ||= ""
|
134
|
+
o[:suffix] ||= ""
|
135
|
+
|
136
|
+
# begin
|
137
|
+
collision = 0
|
138
|
+
path = "#{o[:dir]}/#{o[:prefix]}#{$$}-#{(Time.time*100_000).to_i.to_s(36)}"
|
139
|
+
orgi_path = path.dup
|
140
|
+
while exists?(path)
|
141
|
+
path = orgi_path+ collision.to_s
|
142
|
+
collision +=1
|
143
|
+
end
|
144
|
+
path << o[:suffix]
|
145
|
+
|
146
|
+
path
|
147
|
+
end # def mktmpname
|
148
|
+
private :_mktmpname
|
149
|
+
|
150
|
+
# rm file only
|
151
|
+
#
|
152
|
+
# @param [String] *paths support globbing
|
153
|
+
# @return [nil]
|
154
|
+
def rm(*paths)
|
155
|
+
glob(*paths) { |pa|
|
156
|
+
next if not pa.exists?
|
157
|
+
File.delete(pa.p)
|
158
|
+
}
|
159
|
+
end
|
160
|
+
|
161
|
+
# rm directory only. still remove if directory is not empty.
|
162
|
+
#
|
163
|
+
# @param [String] *paths support globbing
|
164
|
+
# @return [nil]
|
165
|
+
def rmdir *paths
|
166
|
+
glob(*paths) { |pa|
|
167
|
+
raise Errno::ENOTDIR, "-- #{pa}" if not pa.directory?
|
168
|
+
_rmdir(pa)
|
169
|
+
}
|
170
|
+
end
|
171
|
+
|
172
|
+
# rm recusive, rm both file and directory
|
173
|
+
#
|
174
|
+
# @see rm
|
175
|
+
# @return [nil]
|
176
|
+
def rm_r(*paths)
|
177
|
+
glob(*paths){ |pa|
|
178
|
+
next if not pa.exists?
|
179
|
+
pa.directory? ? _rmdir(pa) : File.delete(pa.p)
|
180
|
+
}
|
181
|
+
end
|
182
|
+
|
183
|
+
# rm_r(path) if condition is true
|
184
|
+
#
|
185
|
+
# @example
|
186
|
+
# Pa.rm_if '/tmp/**/*.rb' do |pa|
|
187
|
+
# pa.name == 'old'
|
188
|
+
# end
|
189
|
+
#
|
190
|
+
# @param [String] *paths support globbing
|
191
|
+
# @yield [path]
|
192
|
+
# @yieldparam [Pa] path
|
193
|
+
# @yieldreturn [Boolean] rm_r path if true
|
194
|
+
# @return [nil]
|
195
|
+
def rm_if(*paths, &blk)
|
196
|
+
glob(*paths) do |pa|
|
197
|
+
rm_r pa if blk.call(pa)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
# I'm recusive
|
202
|
+
# param@ [Pa] path
|
203
|
+
def _rmdir(pa, o={})
|
204
|
+
return if not pa.exists?
|
205
|
+
pa.each {|pa1|
|
206
|
+
pa1.directory? ? _rmdir(pa1, o) : File.delete(pa1.p)
|
207
|
+
}
|
208
|
+
pa.directory? ? Dir.rmdir(pa.p) : File.delete(pa.p)
|
209
|
+
end
|
210
|
+
private :_rmdir
|
211
|
+
|
212
|
+
# copy
|
213
|
+
#
|
214
|
+
# cp file dir
|
215
|
+
# cp 'a', 'dir' #=> dir/a
|
216
|
+
# cp 'a', 'dir/a' #=> dir/a
|
217
|
+
#
|
218
|
+
# cp file1 file2 .. dir
|
219
|
+
# cp ['a','b'], 'dir' #=> dir/a dir/b
|
220
|
+
#
|
221
|
+
# @example
|
222
|
+
# cp '*', 'dir' do |src, dest, o|
|
223
|
+
# skip if src.name=~'.o$'
|
224
|
+
# dest.replace 'dirc' if src.name=="foo"
|
225
|
+
# yield # use yield to do the actuactal cp work
|
226
|
+
# end
|
227
|
+
#
|
228
|
+
# @overload cp(src_s, dest, o)
|
229
|
+
# @param [Array<String>, String] src_s support globbing
|
230
|
+
# @param [String,Pa] dest
|
231
|
+
# @param [Hash] o option
|
232
|
+
# @option o [Boolean] :mkdir mkdir(dest) if dest not exists.
|
233
|
+
# @option o [Boolean] :verbose puts cmd when execute
|
234
|
+
# @option o [Boolean] :folsymlink follow symlink
|
235
|
+
# @option o [Boolean] :overwrite overwrite dest file if dest is a file
|
236
|
+
# @return [nil]
|
237
|
+
# @overload cp(src_s, dest, o)
|
238
|
+
# @yield [src,dest,o]
|
239
|
+
# @return [nil]
|
240
|
+
def cp(src_s, dest, o={}, &blk)
|
241
|
+
srcs = glob(*Array.wrap(src_s))
|
242
|
+
dest = Pa(dest)
|
243
|
+
|
244
|
+
if o[:mkdir] and (not dest.exists?)
|
245
|
+
mkdir dest
|
246
|
+
end
|
247
|
+
|
248
|
+
# cp file1 file2 .. dir
|
249
|
+
if srcs.size>1 and (not dest.directory?)
|
250
|
+
raise Errno::ENOTDIR, "dest not a directory when cp more than one src -- #{dest}"
|
251
|
+
end
|
252
|
+
|
253
|
+
srcs.each do |src|
|
254
|
+
dest1 = dest.directory? ? dest.join(src.b) : dest
|
255
|
+
|
256
|
+
if blk
|
257
|
+
blk.call src, dest1, o, proc{_copy(src, dest1, o)}
|
258
|
+
else
|
259
|
+
_copy src, dest1, o
|
260
|
+
end
|
261
|
+
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
|
266
|
+
# I'm recursive
|
267
|
+
#
|
268
|
+
# @param [Pa] src
|
269
|
+
# @param [Pa] dest
|
270
|
+
def _copy(src, dest, o={})
|
271
|
+
raise Errno::EEXIST, "dest exists -- #{dest}" if dest.exists? and (not o[:overwrite])
|
272
|
+
|
273
|
+
case type=src.type
|
274
|
+
when "file", "socket"
|
275
|
+
puts "cp #{src} #{dest}" if o[:verbose]
|
276
|
+
File.copy_stream(src.p, dest.p)
|
277
|
+
when "directory"
|
278
|
+
begin
|
279
|
+
mkdir dest
|
280
|
+
puts "mkdir #{dest}" if o[:verbose]
|
281
|
+
rescue Errno::EEXIST
|
282
|
+
end
|
283
|
+
each(src) { |pa|
|
284
|
+
_copy(pa, dest.join(pa.b), o)
|
285
|
+
}
|
286
|
+
when "symlink"
|
287
|
+
if o[:folsymlink]
|
288
|
+
_copy(src.readlink, dest)
|
289
|
+
else
|
290
|
+
symln(src.readlink, dest, force: true)
|
291
|
+
puts "symlink #{src} #{dest}" if o[:verbose]
|
292
|
+
end
|
293
|
+
when "unknow"
|
294
|
+
raise EUnKnownType, "Can't handle unknow type(#{:type}) -- #{src}"
|
295
|
+
end
|
296
|
+
|
297
|
+
# chmod chown utime
|
298
|
+
src_stat = o[:folsymlink] ? stat(src) : lstat(src)
|
299
|
+
begin
|
300
|
+
chmod(src_stat.mode, dest)
|
301
|
+
chown(src_stat.uid, src_stat.gid, dest)
|
302
|
+
utime(src_stat.atime, src_stat.mtime, dest)
|
303
|
+
rescue Errno::ENOENT
|
304
|
+
end
|
305
|
+
end # _copy
|
306
|
+
private :_copy
|
307
|
+
|
308
|
+
# move, use rename for same device. and cp for cross device.
|
309
|
+
# @see cp
|
310
|
+
#
|
311
|
+
# @param [Hash] o option
|
312
|
+
# @option o [Boolean] :verbose
|
313
|
+
# @option o [Boolean] :mkdir
|
314
|
+
# @option o [Boolean] :overwrite
|
315
|
+
# @return [nil]
|
316
|
+
def mv(src_s, dest, o={}, &blk)
|
317
|
+
srcs = glob(*Array.wrap(src_s))
|
318
|
+
dest = Pa(dest)
|
319
|
+
|
320
|
+
if o[:mkdir] and (not dest.exists?)
|
321
|
+
mkdir dest
|
322
|
+
end
|
323
|
+
|
324
|
+
# mv file1 file2 .. dir
|
325
|
+
if srcs.size>1 and (not dest.directory?)
|
326
|
+
raise Errno::ENOTDIR, "dest not a directory when mv more than one src -- #{dest}"
|
327
|
+
end
|
328
|
+
|
329
|
+
srcs.each do |src|
|
330
|
+
dest1 = dest.directory? ? dest.join(src.b) : dest
|
331
|
+
|
332
|
+
if blk
|
333
|
+
blk.call src, dest1, o, proc{_move(src, dest1, o)}
|
334
|
+
else
|
335
|
+
_move src, dest1, o
|
336
|
+
end
|
337
|
+
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
# I'm recusive
|
342
|
+
#
|
343
|
+
# _move "file", "dir/file"
|
344
|
+
#
|
345
|
+
# @param [Pa] src
|
346
|
+
# @param [Pa] dest
|
347
|
+
def _move(src, dest, o)
|
348
|
+
raise Errno::EEXIST, "dest exists -- #{dest}" if dest.exists? and (not o[:overwrite])
|
349
|
+
|
350
|
+
# overwrite. mv "dir", "dira" and 'dira' exists and is a directory.
|
351
|
+
if dest.exists? and dest.directory?
|
352
|
+
ls(src) { |pa|
|
353
|
+
dest1 = dest.join(pa.b)
|
354
|
+
_move pa, dest1, o
|
355
|
+
}
|
356
|
+
rm_r src
|
357
|
+
|
358
|
+
else
|
359
|
+
begin
|
360
|
+
rm_r dest if o[:overwrite] and dest.exists?
|
361
|
+
puts "rename #{src} #{dest}" if o[:verbose]
|
362
|
+
File.rename(src.p, dest.p)
|
363
|
+
rescue Errno::EXDEV # cross-device
|
364
|
+
_copy(src, dest, o)
|
365
|
+
rm_r src
|
366
|
+
end
|
367
|
+
|
368
|
+
end
|
369
|
+
end # def _move
|
370
|
+
private :_move
|
371
|
+
|
372
|
+
|
373
|
+
end
|
374
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
=begin
|
2
|
+
== ls family
|
3
|
+
* Dir[*path] _support globbing_
|
4
|
+
* Pa.glob(*path,o),(){} _support globbing with option and block_
|
5
|
+
* each(path),(){} each_r(),(){} _support Enumerator. not support globbing_
|
6
|
+
* ls(path) ls_r(path) _sample ls. not support globbing._
|
7
|
+
=== Example
|
8
|
+
each(".") do |pa|
|
9
|
+
p pa
|
10
|
+
end
|
11
|
+
|
12
|
+
each(".").with_index(2){|pa,i| ... }
|
13
|
+
=end
|
14
|
+
class Pa
|
15
|
+
module Directory
|
16
|
+
|
17
|
+
# path globbing, exclude '.' '..' for :dotmatch
|
18
|
+
# @note glob is * ** ? [set] {a,b}
|
19
|
+
#
|
20
|
+
# @overload glob(*paths, o={})
|
21
|
+
# @param [String] path
|
22
|
+
# @param [Hash] o option
|
23
|
+
# @option o [Boolean] :dotmatch glob not match dot file by default.
|
24
|
+
# @option o [Boolean] :pathname wildcard doesn't match /
|
25
|
+
# @option o [Boolean] :noescape makes '\\' ordinary
|
26
|
+
# @return [Array<Pa>]
|
27
|
+
# @overload glob(*paths, o={})
|
28
|
+
# @yieldparam [Pa] path
|
29
|
+
# @return [nil]
|
30
|
+
def glob(*args, &blk)
|
31
|
+
paths, o = args.extract_options
|
32
|
+
paths.map!{|v|get(v)}
|
33
|
+
|
34
|
+
flag = 0
|
35
|
+
o.each do |option, value|
|
36
|
+
flag |= File.const_get("FNM_#{option.upcase}") if value
|
37
|
+
end
|
38
|
+
|
39
|
+
ret = Dir.glob(paths, flag)
|
40
|
+
|
41
|
+
# delete . .. for '.*'
|
42
|
+
ret.tap{|v|v.delete(*%w(. ..))}
|
43
|
+
ret.map!{|v|Pa(v)}
|
44
|
+
|
45
|
+
if blk
|
46
|
+
ret.each {|pa|
|
47
|
+
blk.call pa
|
48
|
+
}
|
49
|
+
else
|
50
|
+
ret
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# is directory empty?
|
55
|
+
#
|
56
|
+
# @param [String] path
|
57
|
+
# @return [Boolean]
|
58
|
+
def empty?(path) Dir.entries(get(path)).empty? end
|
59
|
+
|
60
|
+
# traverse directory
|
61
|
+
# @note return if not a directory.
|
62
|
+
#
|
63
|
+
# @example
|
64
|
+
# each '.' do |pa|
|
65
|
+
# p pa.path
|
66
|
+
# end
|
67
|
+
# # => '/home' ..
|
68
|
+
#
|
69
|
+
# @overload each(path=".", o={})
|
70
|
+
# @param [String,Pa] path
|
71
|
+
# @prarm [Hash] o
|
72
|
+
# @option o [Boolean] :nodot (nil) include dot file
|
73
|
+
# @option o [Boolean] :nobackup (nil) include backup file
|
74
|
+
# @return [Enumerator<Pa>]
|
75
|
+
# @overload each(path=".", o={})
|
76
|
+
# @yieldparam [Pa] path
|
77
|
+
# @return [nil]
|
78
|
+
def each(*args, &blk)
|
79
|
+
return Pa.to_enum(:each, *args) if not blk
|
80
|
+
|
81
|
+
(path,), o = args.extract_options
|
82
|
+
pa = Pa(path || ".")
|
83
|
+
return if not pa.directory?
|
84
|
+
|
85
|
+
Dir.foreach pa.p do |name|
|
86
|
+
next if %w(. ..).include? name
|
87
|
+
next if o[:nodot] and name=~/^\./
|
88
|
+
next if o[:nobackup] and name=~/~$/
|
89
|
+
|
90
|
+
blk.call pa.join(name)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# each with recursive
|
95
|
+
# @see each
|
96
|
+
#
|
97
|
+
# * each_r() skip Exception
|
98
|
+
# * each_r(){pa, err}
|
99
|
+
#
|
100
|
+
# @overload each_r(path=".", o={})
|
101
|
+
# @return [Enumerator<Pa>]
|
102
|
+
# @overload each_r(path=".", o={})
|
103
|
+
# @yield [pa,err]
|
104
|
+
# @return [nil]
|
105
|
+
def each_r(*args, &blk)
|
106
|
+
return Pa.to_enum(:each_r, *args) if not blk
|
107
|
+
|
108
|
+
(path,), o = args.extract_options
|
109
|
+
path ||= "."
|
110
|
+
|
111
|
+
_each_r(Pa(path), "", o, &blk)
|
112
|
+
end
|
113
|
+
|
114
|
+
def _each_r pa, relative, o, &blk
|
115
|
+
each(pa, o) do |pa1|
|
116
|
+
relative1 = Pa.join(relative, pa1.b)
|
117
|
+
blk.call pa1, relative1
|
118
|
+
if pa1.directory?
|
119
|
+
_each_r(pa1, relative1, o, &blk)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
rescue Errno::ENOENT, Errno::EPERM => e
|
123
|
+
blk.call pa, relative, e
|
124
|
+
end
|
125
|
+
private :_each_r
|
126
|
+
|
127
|
+
# list directory contents
|
128
|
+
# @see each
|
129
|
+
#
|
130
|
+
# @return [Array<String>]
|
131
|
+
def ls(*args)
|
132
|
+
each(*args).with_object([]){|pa,m| m<<pa.b}
|
133
|
+
end
|
134
|
+
|
135
|
+
# ls with recursive
|
136
|
+
# @see each
|
137
|
+
#
|
138
|
+
# @return [Array<String>]
|
139
|
+
def ls_r(*args)
|
140
|
+
each_r(*args).with_object([]){|pa,m| m<<pa.b}
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
end
|