tagen 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
-