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 +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
|
-
|