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 +1 -1
- metadata +3 -8
- data/lib/tagen/core/pa.rb +0 -165
- data/lib/tagen/core/pa/cmd.rb +0 -409
- data/lib/tagen/core/pa/dir.rb +0 -166
- data/lib/tagen/core/pa/path.rb +0 -301
- data/lib/tagen/core/pa/state.rb +0 -67
data/version.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 1.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-
|
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
|
data/lib/tagen/core/pa.rb
DELETED
@@ -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
|
-
|
data/lib/tagen/core/pa/cmd.rb
DELETED
@@ -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
|
data/lib/tagen/core/pa/dir.rb
DELETED
@@ -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
|
data/lib/tagen/core/pa/path.rb
DELETED
@@ -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
|
-
|
data/lib/tagen/core/pa/state.rb
DELETED
@@ -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
|
-
|