tagen 1.0.0 → 1.0.1

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/version.rb CHANGED
@@ -2,7 +2,7 @@ module Tagen
2
2
  module VERSION
3
3
  MAJOR = 1
4
4
  MINOR = 0
5
- PATCH = 0
5
+ PATCH = 1
6
6
 
7
7
  IS = [MAJOR, MINOR, PATCH].join(".")
8
8
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 1
7
7
  - 0
8
- - 0
9
- version: 1.0.0
8
+ - 1
9
+ version: 1.0.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Guten
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-06-07 00:00:00 +08:00
17
+ date: 2011-06-08 00:00:00 +08:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -81,11 +81,6 @@ files:
81
81
  - lib/tagen/core/numeric.rb
82
82
  - lib/tagen/core/object.rb
83
83
  - lib/tagen/core/open_option.rb
84
- - lib/tagen/core/pa.rb
85
- - lib/tagen/core/pa/cmd.rb
86
- - lib/tagen/core/pa/dir.rb
87
- - lib/tagen/core/pa/path.rb
88
- - lib/tagen/core/pa/state.rb
89
84
  - lib/tagen/core/process.rb
90
85
  - lib/tagen/core/re.rb
91
86
  - lib/tagen/core/string.rb
@@ -1,165 +0,0 @@
1
- =begin rdoc
2
- Pa(Path) is similary to Pathname, but more powerful.
3
- it combines fileutils, tmpdir, find, tempfile, File, Dir, Pathname
4
-
5
- all class methods support Pa as parameter.
6
-
7
- Examples:
8
- ---------
9
- pa = Pa('/home/a.vim')
10
- pa.dir #=> '/home'
11
- pa.base #=> 'a.vim'
12
- pa.name #=> 'a'
13
- pa.ext #=> 'vim'
14
- pa.fext #=> '.vim'
15
-
16
- Filename parts:
17
- ---------
18
- /home/guten.ogg
19
- base: guten.ogg
20
- dir: /home
21
- ext: ogg
22
- name: guten
23
-
24
- Additional method list
25
- ---------------------
26
- * Pa.absolute _alias from `File.absolute_path`_
27
- * Pa.expand _aliss from `File.expand_path`_
28
-
29
- === create, modify path
30
- Example1:
31
- pa = Pa('/home/foo')
32
- pa.join('a.txt') #=> new Pa('/home/foo/a.txt')
33
-
34
- Example2:
35
- pa1 = Pa('/home/foo/a.txt')
36
- pa2 = Pa('/home/bar/b.txt')
37
- pa1+'~' #=> new Pa('/home/foo/a.txt~')
38
- Pa.join(pa1.dir, pa2.base) #=> '/home/foo/b.txt'
39
-
40
- Example3:
41
- pa1 = Pa('/home/foo/a.txt')
42
- pa2 = Pa('/home/bar')
43
- pa2.join(pa1.base) #=> new Pa('/home/bar/a.txt')
44
-
45
- **Attributes**
46
-
47
- name abbr description
48
-
49
- path p
50
- absolute a absolute path
51
- dir d dirname of a path
52
- base b basename of a path
53
- name n filename of a path
54
- ext e extname of a path, return "" or "ogg"
55
- fext fe return "" or ".ogg"
56
-
57
- == used with rspec
58
-
59
- File.exists?(path).should be_true
60
- Pa(path).should be_exists
61
-
62
- =end
63
- class Pa
64
- Error = Class.new Exception
65
- EUnkonwType = Class.new Error
66
-
67
- attr_reader :path
68
-
69
- # @param [String,#path] path
70
- def initialize path
71
- @path = path.respond_to?(:path) ? path.path : path
72
- initialize_variables
73
- end
74
-
75
- chainable = Module.new do
76
- def initialize_variables; end
77
- end
78
- include chainable
79
-
80
- alias p path
81
-
82
- # @param [String,#path]
83
- # @return [Pa] the same Pa object
84
- def replace path
85
- @path = path.respond_to?(:path) ? path.path : path
86
- initialize_variables
87
- end
88
-
89
- # return '#<Pa @path="foo", @absolute="/home/foo">'
90
- #
91
- # @return [String]
92
- def inspect
93
- ret="#<" + self.class.to_s + " "
94
- ret += "@path=\"#{path}\", @absolute=\"#{absolute}\""
95
- ret += " >"
96
- ret
97
- end
98
-
99
- # return '/home/foo'
100
- #
101
- # @return [String] path
102
- def to_s
103
- @path
104
- end
105
-
106
- # missing method goes to Pa.class-method
107
- def method_missing(name, *args, &blk)
108
- ret = self.class.__send__(name, path, *args, &blk)
109
-
110
- case ret
111
-
112
- # e.g. readlink ..
113
- when String
114
- Pa(ret)
115
-
116
- # e.g. directory?
117
- else
118
- ret
119
- end
120
-
121
- end
122
-
123
-
124
- end
125
-
126
- class Pa
127
- module ClassMethods
128
- UNDEFS = [:open, :fstat]
129
-
130
- # missing method goes to File class method
131
- def method_missing name, *args, &blk
132
- raise NoMethodError, name.inspect if UNDEFS.include?(name)
133
- return if args.size>1
134
- File.__send__ name, get(args[0]), &blk
135
- end
136
- end
137
- end
138
-
139
- require_relative "pa/path"
140
- require_relative "pa/cmd"
141
- require_relative "pa/dir"
142
- require_relative "pa/state"
143
- class Pa
144
- extend ClassMethods
145
- extend ClassMethods::Path
146
- extend ClassMethods::Dir
147
- extend ClassMethods::State
148
- extend ClassMethods::Cmd
149
-
150
- include Path
151
- include State
152
- end
153
-
154
- module Kernel
155
- private
156
- # a very convient function.
157
- #
158
- # @example
159
- # Pa('/home').exists?
160
- def Pa(path)
161
- return path if Pa===path
162
- Pa.new path
163
- end
164
- end
165
-
@@ -1,409 +0,0 @@
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 ClassMethods::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 {|path|
43
- if File.exists?(path)
44
- o[:force] ? next : raise(Errno::EEXIST, "File exist -- #{path}")
45
- end
46
-
47
- mkdir(File.dirname(p)) if o[:mkdir]
48
-
49
- if win32?
50
- # win32 BUG. must f.write("") then file can be deleted.
51
- File.open(p, "w"){|f| f.chmod(o[:mode]); f.write("")}
52
- else
53
- File.open(p, "w"){|f| f.chmod(o[:mode])}
54
- end
55
- }
56
- end
57
- private :_touch
58
-
59
- # make a directory
60
- #
61
- # @overload mkdir(*paths, o={})
62
- # @param [String, Pa] *paths
63
- # @param [Hash] o option
64
- # @option o [Fixnum] :mode
65
- # @option o [Boolean] :force
66
- # @return [nil]
67
- def mkdir(*args) paths, o = args.extract_options; _mkdir(paths, o) end
68
-
69
- # mkdir force
70
- # @see mkdir
71
- #
72
- # @overload mkdir_f(*paths, o={})
73
- # @return [nil]
74
- def mkdir_f(*args) paths, o = args.extract_options; o[:force]=true; _mkdir(paths, o) end
75
-
76
- def _mkdir(paths, o)
77
- o[:mode] ||= 0744
78
- paths.map!{|v|get(v)}
79
- paths.each {|p|
80
- if File.exists?(p)
81
- o[:force] ? next : raise(Errno::EEXIST, "File exist -- #{p}")
82
- end
83
-
84
- stack = []
85
- until p == stack.last
86
- break if File.exists?(p)
87
- stack << p
88
- p = File.dirname(p)
89
- end
90
-
91
- stack.reverse.each do |path|
92
- Dir.mkdir(path)
93
- File.chmod(o[:mode], path)
94
- end
95
- }
96
- end
97
- private :_mkdir
98
-
99
- # make temp directory
100
- #
101
- # @param [Hash] o options
102
- # @option o [Symbol] :prefix ("")
103
- # @option o [Symbol] :suffix ("")
104
- # @option o [Symbol] :tmpdir (ENV["TEMP"])
105
- # @return [String] path
106
- def mktmpdir(o={}, &blk)
107
- p = _mktmpname(o)
108
- File.mkdir(p)
109
- begin blk.call(p) ensure Dir.delete(p) end if blk
110
- p
111
- end # def mktmpdir
112
-
113
- def home(user=nil) Dir.home end
114
-
115
- # make temp file
116
- # @see mktmpdir
117
- #
118
- # @param [Hash] o options
119
- # @return [String] path
120
- def mktmpfile(o={}, &blk)
121
- p = _mktmpname(o)
122
- begin blk.call(p) ensure File.delete(p) end if blk
123
- p
124
- end # mktmpfile
125
-
126
- def _mktmpname(o={})
127
- # :prefix :suffix :tmpdir
128
- # $$-(time*100_000).to_i.to_s(36)
129
- # parse o
130
- o[:dir] ||= ENV["TEMP"]
131
- o[:prefix] ||= ""
132
- o[:suffix] ||= ""
133
-
134
- # begin
135
- collision = 0
136
- path = "#{o[:dir]}/#{o[:prefix]}#{$$}-#{(Time.time*100_000).to_i.to_s(36)}"
137
- orgi_path = path.dup
138
- while File.exists?(path)
139
- path = orgi_path+ collision.to_s
140
- collision +=1
141
- end
142
- path << o[:suffix]
143
-
144
- path
145
- end # def mktmpname
146
- private :_mktmpname
147
-
148
- # rm file only
149
- #
150
- # @param [String] *paths support globbing
151
- # @return [nil]
152
- def rm *paths
153
- paths, o = paths.extract_options
154
- glob(*paths) { |pa|
155
- if File.directory?(pa.p)
156
- if o[:force]; next else raise Errno::EISDIR, "is a directory -- #{pa.p}" end
157
- end
158
- next if pa.directory?
159
- File.delete(pa.p)
160
- }
161
- end
162
-
163
- def rm_f *paths
164
- paths, o = paths.extract_options
165
- o[:force] = true
166
- rm *paths, o
167
- end
168
-
169
- # rm directory only. still remove if directory is not empty.
170
- #
171
- # @param [String] *paths support globbing
172
- # @return [nil]
173
- def rmdir *paths
174
- paths, o = paths.extract_options
175
- glob(*paths) { |pa|
176
- if not File.directory?(pa.p)
177
- if o[:force]; next else raise Errno::ENOTDIR, "not a directory -- #{pa.p}" end
178
- end
179
- _rmdir(pa)
180
- }
181
- end
182
-
183
- def rmdir_f *paths
184
- paths, o = paths.extract_options
185
- o[:force] = true
186
- rmdir *paths, o
187
- end
188
-
189
- # rm recusive, rm both file and directory
190
- #
191
- # @see rm
192
- # @return [nil]
193
- def rm_r *paths
194
- glob(*paths){ |pa|
195
- File.directory?(pa.p) ? _rmdir(pa) : File.delete(pa.p)
196
- }
197
- end
198
- alias rm_rf rm_r
199
-
200
-
201
- # rm_if(path) if condition is true
202
- #
203
- # @example
204
- # Pa.rm_if '/tmp/**/*.rb' do |pa|
205
- # pa.name == 'old'
206
- # end
207
- #
208
- # @param [String] *paths support globbing
209
- # @yield [path]
210
- # @yieldparam [Pa] path
211
- # @yieldreturn [Boolean] rm_r path if true
212
- # @return [nil]
213
- def rm_if(*paths, &blk)
214
- glob(*paths) do |pa|
215
- rm_r pa if blk.call(pa)
216
- end
217
- end
218
-
219
- # I'm recusive
220
- # param@ [Pa] path
221
- def _rmdir(pa, o={})
222
- return if not File.exists?(pa.p)
223
- pa.each {|pa1|
224
- File.directory?(pa1.p) ? _rmdir(pa1, o) : File.delete(pa1.p)
225
- }
226
- File.directory?(pa.p) ? Dir.rmdir(pa.p) : File.delete(pa.p)
227
- end
228
- private :_rmdir
229
-
230
- # copy
231
- #
232
- # cp file dir
233
- # cp 'a', 'dir' #=> dir/a
234
- # cp 'a', 'dir/a' #=> dir/a
235
- #
236
- # cp file1 file2 .. dir
237
- # cp ['a','b'], 'dir' #=> dir/a dir/b
238
- #
239
- # @example
240
- # cp '*', 'dir' do |src, dest, o|
241
- # skip if src.name=~'.o$'
242
- # dest.replace 'dirc' if src.name=="foo"
243
- # yield # use yield to do the actuactal cp work
244
- # end
245
- #
246
- # @overload cp(src_s, dest, o)
247
- # @param [Array<String>, String] src_s support globbing
248
- # @param [String,Pa] dest
249
- # @param [Hash] o option
250
- # @option o [Boolean] :mkdir mkdir(dest) if dest not exists.
251
- # @option o [Boolean] :verbose puts cmd when execute
252
- # @option o [Boolean] :folsymlink follow symlink
253
- # @option o [Boolean] :force force dest file if dest is a file
254
- # @option o [Boolean] :special special copy, when cp a directory, only mkdir, not cp the directory's content, usefull in Pa.each_r
255
- # @return [nil]
256
- # @overload cp(src_s, dest, o)
257
- # @yield [src,dest,o]
258
- # @return [nil]
259
- def cp(src_s, dest, o={}, &blk)
260
- srcs = glob(*Array.wrap(src_s)).map{|v| v.path}
261
- dest = Pa.get(dest)
262
-
263
- if o[:mkdir] and (not File.exists?(dest))
264
- Pa.mkdir dest
265
- end
266
-
267
- # cp file1 file2 .. dir
268
- if srcs.size>1 and (not File.directory?(dest))
269
- raise Errno::ENOTDIR, "dest not a directory when cp more than one src -- #{dest}"
270
- end
271
-
272
- srcs.each do |src|
273
- dest1 = File.directory?(dest) ? File.join(dest, File.basename(src)) : dest
274
-
275
- if blk
276
- blk.call src, dest1, o, proc{_copy(src, dest1, o)}
277
- else
278
- _copy src, dest1, o
279
- end
280
-
281
- end
282
- end
283
-
284
- def cp_f src_s, dest, o={}, &blk
285
- o[:force] = true
286
- cp src_s, dest, o, &blk
287
- end
288
-
289
- # I'm recursive
290
- #
291
- # @param [String] src
292
- # @param [String] dest
293
- def _copy(src, dest, o={})
294
- raise Errno::EEXIST, "dest exists -- #{dest}" if File.exists?(dest) and (not o[:force])
295
-
296
- case type=File.ftype(src)
297
-
298
- when "file", "socket"
299
- puts "cp #{src} #{dest}" if o[:verbose]
300
- File.copy_stream(src, dest)
301
-
302
- when "directory"
303
- begin
304
- Pa.mkdir dest
305
- puts "mkdir #{dest}" if o[:verbose]
306
- rescue Errno::EEXIST
307
- end
308
-
309
- return if o[:special]
310
-
311
- each(src) { |pa|
312
- _copy(pa.p, File.join(dest, File.basename(pa.p)), o)
313
- }
314
-
315
- when "link" # symbol link
316
- if o[:folsymlink]
317
- _copy(Pa.readlink(src), dest)
318
- else
319
- Pa.symln(Pa.readlink(src), dest, force: true)
320
- puts "symlink #{src} #{dest}" if o[:verbose]
321
- end
322
-
323
- when "unknow"
324
- raise EUnKnownType, "Can't handle unknow type(#{:type}) -- #{src}"
325
- end
326
-
327
- # chmod chown utime
328
- src_stat = o[:folsymlink] ? File.stat(src) : File.lstat(src)
329
- begin
330
- File.chmod(src_stat.mode, dest)
331
- #File.chown(src_stat.uid, src_stat.gid, dest)
332
- File.utime(src_stat.atime, src_stat.mtime, dest)
333
- rescue Errno::ENOENT
334
- end
335
- end # _copy
336
- private :_copy
337
-
338
- # move, use rename for same device. and cp for cross device.
339
- # @see cp
340
- #
341
- # @param [Hash] o option
342
- # @option o [Boolean] :verbose
343
- # @option o [Boolean] :mkdir
344
- # @option o [Boolean] :fore
345
- # @return [nil]
346
- def mv(src_s, dest, o={}, &blk)
347
- srcs = glob(*Array.wrap(src_s)).map{|v| get(v)}
348
- dest = get(dest)
349
-
350
- if o[:mkdir] and (not File.exists?(dest))
351
- mkdir dest
352
- end
353
-
354
- # mv file1 file2 .. dir
355
- if srcs.size>1 and (not File.directory?(dest))
356
- raise Errno::ENOTDIR, "dest not a directory when mv more than one src -- #{dest}"
357
- end
358
-
359
- srcs.each do |src|
360
- dest1 = File.directory?(dest) ? File.join(dest, File.basename(src)) : dest
361
-
362
- if blk
363
- blk.call src, dest1, o, proc{_move(src, dest1, o)}
364
- else
365
- _move src, dest1, o
366
- end
367
-
368
- end
369
- end
370
-
371
- def mv_f src_s, dest, o={}, &blk
372
- o[:force] = true
373
- mv src_s, dest, o, &blk
374
- end
375
-
376
- # I'm recusive
377
- #
378
- # _move "file", "dir/file"
379
- #
380
- # @param [String] src
381
- # @param [String] dest
382
- def _move(src, dest, o)
383
- raise Errno::EEXIST, "dest exists -- #{dest}" if File.exists?(dest) and (not o[:force])
384
-
385
- # :force. mv "dir", "dira" and 'dira' exists and is a directory.
386
- if File.exists?(dest) and File.directory?(dest)
387
- ls(src) { |pa|
388
- dest1 = File.join(dest, File.basename(pa.p))
389
- _move pa.p, dest1, o
390
- }
391
- Pa.rm_r src
392
-
393
- else
394
- begin
395
- Pa.rm_r dest if o[:force] and File.exists?(dest)
396
- puts "rename #{src} #{dest}" if o[:verbose]
397
- File.rename(src, dest)
398
- rescue Errno::EXDEV # cross-device
399
- _copy(src, dest, o)
400
- Pa.rm_r src
401
- end
402
-
403
- end
404
- end # def _move
405
- private :_move
406
-
407
-
408
- end
409
- end
@@ -1,166 +0,0 @@
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 ClassMethods::Dir
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 raise Errno::ENOTDIR, Errno::ENOENT
62
- #
63
- # @example
64
- # each '.' do |pa|
65
- # p pa.path #=> "foo" not "./foo"
66
- # end
67
- # # => '/home' ..
68
- #
69
- # each('.', error: true).with_object([]) do |(pa,err),m|
70
- # ...
71
- # end
72
- #
73
- # @overload each(path=".", o={})
74
- # @param [String,Pa] path
75
- # @prarm [Hash] o
76
- # @option o [Boolean] :nodot (false) include dot file
77
- # @option o [Boolean] :nobackup (false) include backup file
78
- # @option o [Boolean] :error (false) yield(pa, err) instead of raise Errno::EPERM when Dir.open(dir)
79
- # @return [Enumerator<Pa>]
80
- # @overload each(path=".", o={})
81
- # @yieldparam [Pa] path
82
- # @return [nil]
83
- def each(*args, &blk)
84
- return Pa.to_enum(:each, *args) unless blk
85
-
86
- (path,), o = args.extract_options
87
- path = path ? get(path) : "."
88
- raise Errno::ENOENT, "`#{path}' doesn't exists." unless File.exists?(path)
89
- raise Errno::ENOTDIR, "`#{path}' not a directoyr." unless File.directory?(path)
90
-
91
- begin
92
- dir = Dir.open(path)
93
- rescue Errno::EPERM => err
94
- end
95
- raise err if err and !o[:error]
96
-
97
- while (entry=dir.read)
98
- next if %w(. ..).include? entry
99
- next if o[:nodot] and entry=~/^\./
100
- next if o[:nobackup] and entry=~/~$/
101
-
102
- # => "foo" not "./foo"
103
- pa = path=="." ? Pa(entry) : Pa(File.join(path, entry))
104
- if o[:error]
105
- blk.call pa, err
106
- else
107
- blk.call pa
108
- end
109
- end
110
- end
111
-
112
- # each with recursive
113
- # @see each
114
- #
115
- # * each_r() skip Exception
116
- # * each_r(){pa, err}
117
- #
118
- # @overload each_r(path=".", o={})
119
- # @return [Enumerator<Pa>]
120
- # @overload each_r(path=".", o={})
121
- # @yieldparam [Pa] pa
122
- # @yieldparam [String] relative relative path
123
- # @yieldparam [Errno::ENOENT,Errno::EPERM] err
124
- # @return [nil]
125
- def each_r(*args, &blk)
126
- return Pa.to_enum(:each_r, *args) if not blk
127
-
128
- (path,), o = args.extract_options
129
- path ||= "."
130
-
131
- _each_r(path, "", o, &blk)
132
- end
133
-
134
- # @param [String] path
135
- def _each_r path, relative, o, &blk
136
- o.merge!(error: true)
137
- Pa.each(path, o) do |pa1, err|
138
- relative1 = Pa.join(relative, pa1.b)
139
-
140
- blk.call pa1, relative1, err
141
-
142
- if pa1.directory?
143
- _each_r(pa1.p, relative1, o, &blk)
144
- end
145
- end
146
- end
147
- private :_each_r
148
-
149
- # list directory contents
150
- # @see each
151
- #
152
- # @return [Array<String>]
153
- def ls(*args)
154
- each(*args).with_object([]){|pa,m| m<<pa.b}
155
- end
156
-
157
- # ls with recursive
158
- # @see each
159
- #
160
- # @return [Array<String>]
161
- def ls_r(*args)
162
- each_r(*args).with_object([]){|pa,m| m<<pa.base}
163
- end
164
-
165
- end
166
- end
@@ -1,301 +0,0 @@
1
- class Pa
2
- NAME_EXT_PAT = /^(.+?)(?:\.([^.]+))?$/
3
- module ClassMethods::Path
4
-
5
- # alias from File.absolute_path
6
- # @param [String,Pa] path
7
- # @return [String]
8
- def absolute(path); File.absolute_path(get(path)) end
9
-
10
- # alias from File.expand_path
11
- # @param [String,Pa] path
12
- # @return [String]
13
- def expand(path); File.expand_path(get(path)) end
14
-
15
- # shorten a path,
16
- # convert /home/user/file to ~/file
17
- #
18
- # @param [String,Pa] path
19
- # @return [String]
20
- def shorten(path);
21
- get(path).sub(%r!^#{Regexp.escape(ENV["HOME"])}!, "~")
22
- end
23
-
24
- # return current work directory
25
- # @return [String] path
26
- def pwd() Dir.getwd end
27
-
28
- # @return [Pa] path
29
- def pwd2() Pa(Dir.getwd) end
30
-
31
- # change directory
32
- #
33
- # @param [String,Pa] path
34
- def cd(path=ENV["HOME"], &blk) Dir.chdir(get(path), &blk) end
35
-
36
- # get path of an object.
37
- #
38
- # return obj#path if object has a 'path' instance method
39
- #
40
- # @param [String,#path] obj
41
- # @return [String,nil] path
42
- def get obj
43
- if obj.respond_to?(:path)
44
- obj.path
45
- elsif String === obj
46
- obj
47
- else
48
- raise Error, "not support type -- #{obj.inspect}(#{obj.class})"
49
- end
50
- end
51
-
52
- # extname of a path
53
- #
54
- # @example
55
- # "a.ogg" => "ogg"
56
- # "a" => nil
57
- #
58
- # @param [String,Pa] path
59
- # @return [String]
60
- def extname path
61
- _, ext = get(path).match(/\.([^.]+)$/).to_a
62
- ext
63
- end
64
-
65
- # is path an absolute path ?
66
- #
67
- # @param [String,Pa] path
68
- # @return [Boolean]
69
- def absolute?(path) path=get(path); File.absolute_path(path) == path end
70
-
71
- # get a basename of a path
72
- #
73
- # @example
74
- # Pa.basename("foo.bar.c", ext: true) #=> \["foo.bar", "c"]
75
- #
76
- # @param [String,Pa] name
77
- # @param [Hash] o options
78
- # @option o [Boolean, String] :ext (false) return \[name, ext] if true
79
- #
80
- # @return [String] basename of a path unless o[:ext]
81
- # @return [Array<String>] \[name, ext] if o[:ext].
82
- def basename(name, o={})
83
- name = File.basename(get(name))
84
- if o[:ext]
85
- name, ext = name.match(NAME_EXT_PAT).captures
86
- [ name, (ext || "")]
87
- else
88
- name
89
- end
90
- end
91
-
92
- # split path
93
- #
94
- # @example
95
- # path="/home/a/file"
96
- # split(path) #=> "/home/a", "file"
97
- # split(path, :all) #=> "/", "home", "a", "file"
98
- #
99
- # @param [String,Pa] name
100
- # @param [Hash] o option
101
- # @option o [Boolean] :all split all parts
102
- # @return [Array<String>]
103
- def split(name, o={})
104
- dir, fname = File.split(get(name))
105
- ret = Array.wrap(basename(fname, o))
106
-
107
- if o[:all]
108
- loop do
109
- dir1, fname = File.split(dir)
110
- break if dir1 == dir
111
- ret.unshift fname
112
- dir = dir1
113
- end
114
- end
115
- ret.unshift dir
116
- ret
117
- end
118
-
119
- # join paths, skip nil and empty string.
120
- #
121
- # @param [*Array<String>] *paths
122
- # @return [String]
123
- def join *paths
124
- paths.map!{|v|get(v)}
125
-
126
- # skip nil
127
- paths.compact!
128
-
129
- # skip empty string
130
- paths.delete("")
131
-
132
- File.join(*paths)
133
- end
134
-
135
- # get parent path
136
- #
137
- # @param [String,Pa] path
138
- # @param [Fixnum] n up level
139
- # @return [String]
140
- def parent path, n=1
141
- path = get(path)
142
- n.times do
143
- path = File.dirname(path)
144
- end
145
- path
146
- end
147
-
148
- # link
149
- #
150
- # @overload ln(src, dest)
151
- # @overload ln([src,..], directory)
152
- #
153
- # @param [Array<String>, String] src_s support globbing
154
- # @param [String,Pa] dest
155
- # @param [Hash] o option
156
- # @option o [Boolean] :force overwrite if exists.
157
- # @return [nil]
158
- def ln(src_s, dest, o={}) _ln(File.method(:link), src_s, dest, o) end
159
-
160
- # ln force
161
- #
162
- # @see ln
163
- # @return [nil]
164
- def ln_f(src_s, dest, o) o[:force]=true; _ln(File.method(:link), src_s, dest, o) end
165
-
166
- # symbol link
167
- #
168
- # @see ln
169
- # @return [nil]
170
- def symln(src_s, dest, o) _ln(File.method(:symlink), src_s, dest, o) end
171
- alias symlink ln
172
-
173
- # symln force
174
- #
175
- # @see ln
176
- # @return [nil]
177
- def symln_f(src_s, dest, o) o[:force]=true; _ln(File.method(:symlink), src_s, dest, o) end
178
-
179
- # @param [Array,String,#path] src_s
180
- # @param [String,#path] dest
181
- def _ln(method, src_s, dest, o={})
182
- dest = get(dest)
183
- glob(*Array.wrap(src_s)) {|src|
184
- src = get(src)
185
- dest = File.join(dest, File.basename(src)) if File.directory?(dest)
186
- Pa.rm_r(dest) if o[:force] and File.exists?(dest)
187
- method.call(src, dest)
188
- }
189
- end
190
- private :_ln
191
-
192
- # @see File.readlink
193
- def readlink(path) File.readlink(get(path)) end
194
-
195
- # is path a dangling symlink?
196
- #
197
- # a dangling symlink is a dead symlink.
198
- #
199
- # @param [String,Pa] path
200
- # @return [Boolean]
201
- def dangling? path
202
- path=get(path)
203
- if File.symlink?(path)
204
- src = File.readlink(path)
205
- not File.exists?(src)
206
- else
207
- nil
208
- end
209
- end # def dsymlink?
210
-
211
- def realpath(path) File.realpath(get(path)) end
212
-
213
- end
214
- end
215
-
216
- class Pa
217
- =begin
218
-
219
- attribute absolute and dir return String, method absolute_path(), dirname() return Pa
220
-
221
- Pa("/home/a").dir #=> "/home"
222
- Pa("/home/a").dirname #=> Pa("/home")
223
-
224
- == methods from String
225
- * +
226
- * [g]sub[!] match =~
227
- * start_with? end_with?
228
-
229
- =end
230
- module Path
231
- # @return [String]
232
- attr_reader :absolute, :dir, :base, :name, :ext, :fext, :short
233
-
234
- def initialize_variables
235
- super
236
- @absolute = File.absolute_path(@path)
237
- @dir = File.dirname(@path)
238
- @base = File.basename(@path)
239
- @name, @ext = @base.match(NAME_EXT_PAT).captures
240
- @ext ||= ""
241
- @fext = @ext.empty? ? "" : "."+@ext
242
- end
243
-
244
- alias a absolute
245
- alias d dir
246
- alias b base
247
- alias n name
248
- alias fname base
249
- alias fn fname
250
- alias e ext
251
- alias fe fext
252
-
253
- def short
254
- @short ||= Pa.shorten(@path)
255
- end
256
-
257
- # @return [Pa] absolute path
258
- def absolute2() @absolute2 ||= Pa(absolute) end
259
-
260
- # @return [Pa] dirname
261
- # @example
262
- # Pa(__FILE__).dirname.join('.opts')
263
- def dir2() @dir2 ||= Pa(dir) end
264
-
265
- # add string to path
266
- #
267
- # @example
268
- # pa = Pa('/home/foo/a.txt')
269
- # pa+'~' #=> new Pa('/home/foo/a.txt~')
270
- #
271
- # @param [String] str
272
- # @return [Pa]
273
- def +(str) Pa(path+str) end
274
-
275
- # @return [Pa]
276
- def sub(*args,&blk) Pa(path.sub(*args,&blk)) end
277
-
278
- # @return [Pa]
279
- def gsub(*args,&blk) Pa(path.gsub(*args,&blk)) end
280
-
281
- # @return [Pa]
282
- def sub!(*args,&blk) self.replace path.sub(*args,&blk) end
283
-
284
- # @return [Pa]
285
- def gsub!(*args,&blk) self.replace path.gsub(*args,&blk) end
286
-
287
- # @return [MatchData]
288
- def match(*args,&blk) path.match(*args,&blk) end
289
-
290
- # @return [Boolean]
291
- def start_with?(*args) path.start_with?(*args) end
292
-
293
- # @return [Boolean]
294
- def end_with?(*args) path.end_with?(*args) end
295
-
296
- def =~(regexp) path =~ regexp end
297
-
298
- def ==(other) self.path == other.path end
299
- end
300
- end
301
-
@@ -1,67 +0,0 @@
1
- class Pa
2
- module ClassMethods::State
3
-
4
- # @see File.chmod
5
- def chmod(mode, *paths) paths.map!{|v|get(v)}; File.chmod(mode, *paths) end
6
-
7
- # @see File.lchmod
8
- def lchmod(mode, *paths) paths.map!{|v|get(v)}; File.lchmod(mode, *paths) end
9
-
10
- # @see File.chown
11
- def chown(user, group=nil, *paths) paths.map!{|v|get(v)}; File.chown(user, group, *paths) end
12
-
13
- # @see File.lchown
14
- def lchown(user, group=nil, *paths) paths.map!{|v|get(v)}; File.lchown(user, group, *paths) end
15
-
16
- # @see File.utime
17
- def utime(atime, mtime, *paths) paths.map!{|v|get(v)}; File.utime(atime, mtime, *paths) end
18
-
19
-
20
- # get file type
21
- #
22
- # file types:
23
- # "chardev" "blockdev" "symlink" ..
24
- #
25
- # @param [String] path
26
- # @return [String]
27
- def type(path)
28
- case (t=File.ftype(get(path)))
29
- when "characterSpecial"
30
- "chardev"
31
- when "blockSpecial"
32
- "blockdev"
33
- when "link"
34
- "symlink"
35
- else
36
- t
37
- end
38
- end # def type
39
-
40
-
41
- # is path a mountpoint?
42
- #
43
- # @param[String] path
44
- # @return [Boolean]
45
- def mountpoint? path
46
- path=get(path)
47
- begin
48
- stat1 = File.lstat(path)
49
- stat2 = File.lstat(File.join(path, '..'))
50
- stat1.dev == stat2.dev && stat1.ino == stat2.ino || stat1.dev != stat2.dev
51
- rescue Errno::ENOENT
52
- false
53
- end
54
- end
55
- end
56
-
57
- module State
58
- def chmod(mode); File.chmod(mode, path) end
59
- def lchmod(mode); File.lchmod(mode, path) end
60
- def chown(uid, gid=nil); File.chown(uid, gid, path) end
61
- def lchown(uid, gid=nil); File.lchown(uid, gid, path) end
62
- def utime(atime, mtime); File.utime(atime, mtime, path) end
63
- end
64
-
65
- end
66
-
67
-