pa 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +20 -0
- data/LICENSE +20 -0
- data/README.md +57 -0
- data/Ragfile +5 -0
- data/lib/pa/cmd.rb +410 -0
- data/lib/pa/core.rb +106 -0
- data/lib/pa/dir.rb +195 -0
- data/lib/pa/path.rb +301 -0
- data/lib/pa/state.rb +67 -0
- data/lib/pa.rb +175 -0
- data/pa.gemspec +22 -0
- data/pa.watchr +22 -0
- data/spec/pa/cmd_spec.rb +278 -0
- data/spec/pa/dir_spec.rb +137 -0
- data/spec/pa/path_spec.rb +142 -0
- data/spec/pa/state_spec.rb +7 -0
- data/spec/spec_helper.rb +2 -0
- data/version.rb +9 -0
- metadata +111 -0
data/lib/pa/dir.rb
ADDED
@@ -0,0 +1,195 @@
|
|
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
|
+
|
8
|
+
=== Example
|
9
|
+
tmp/
|
10
|
+
filea
|
11
|
+
dira/fileb
|
12
|
+
|
13
|
+
ls("tmp") => ["filea", "dira"]
|
14
|
+
ls_r("tmp") => ["filea", "dira", "dira/fileb"]
|
15
|
+
ls_r("tmp"){|pa, rel| rel.count('/')==1} => ["dira/fileb"]
|
16
|
+
|
17
|
+
each("tmp") => Enumerate<Pa>
|
18
|
+
each("tmp") {|pa| Pa.rm pa if pa.file?}
|
19
|
+
each("tmp").with_object([]){|pa,m| m<<pa.dir} #=> ["tmp", "tmp/dira"]
|
20
|
+
|
21
|
+
=end
|
22
|
+
class Pa
|
23
|
+
module ClassMethods::Dir
|
24
|
+
|
25
|
+
# path globbing, exclude '.' '..' for :dotmatch
|
26
|
+
# @note glob is * ** ? [set] {a,b}
|
27
|
+
#
|
28
|
+
# @overload glob(*paths, o={})
|
29
|
+
# @param [String] path
|
30
|
+
# @param [Hash] o option
|
31
|
+
# @option o [Boolean] :dotmatch glob not match dot file by default.
|
32
|
+
# @option o [Boolean] :pathname wildcard doesn't match /
|
33
|
+
# @option o [Boolean] :noescape makes '\\' ordinary
|
34
|
+
# @return [Array<Pa>]
|
35
|
+
# @overload glob(*paths, o={})
|
36
|
+
# @yieldparam [Pa] path
|
37
|
+
# @return [nil]
|
38
|
+
def glob(*args, &blk)
|
39
|
+
paths, o = args.extract_options
|
40
|
+
paths.map!{|v|get(v)}
|
41
|
+
|
42
|
+
flag = 0
|
43
|
+
o.each do |option, value|
|
44
|
+
flag |= File.const_get("FNM_#{option.upcase}") if value
|
45
|
+
end
|
46
|
+
|
47
|
+
ret = Dir.glob(paths, flag)
|
48
|
+
|
49
|
+
# delete . .. for '.*'
|
50
|
+
ret.tap{|paths| %w(. ..).each{|v| paths.delete(v)}}
|
51
|
+
ret.map!{|path|Pa(path)}
|
52
|
+
|
53
|
+
if blk
|
54
|
+
ret.each {|pa|
|
55
|
+
blk.call pa
|
56
|
+
}
|
57
|
+
else
|
58
|
+
ret
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# is directory empty?
|
63
|
+
#
|
64
|
+
# @param [String] path
|
65
|
+
# @return [Boolean]
|
66
|
+
def empty?(path) Dir.entries(get(path)).empty? end
|
67
|
+
|
68
|
+
# traverse directory
|
69
|
+
# @note raise Errno::ENOTDIR, Errno::ENOENT
|
70
|
+
#
|
71
|
+
# @example
|
72
|
+
# each '.' do |pa|
|
73
|
+
# p pa.path #=> "foo" not "./foo"
|
74
|
+
# end
|
75
|
+
# # => '/home' ..
|
76
|
+
#
|
77
|
+
# each('.', error: true).with_object([]) do |(pa,err),m|
|
78
|
+
# ...
|
79
|
+
# end
|
80
|
+
#
|
81
|
+
# @overload each(path=".", o={})
|
82
|
+
# @param [String,Pa] path
|
83
|
+
# @prarm [Hash] o
|
84
|
+
# @option o [Boolean] :nodot (false) include dot file
|
85
|
+
# @option o [Boolean] :nobackup (false) include backup file
|
86
|
+
# @option o [Boolean] :error (false) yield(pa, err) instead of raise Errno::EPERM when Dir.open(dir)
|
87
|
+
# @return [Enumerator<Pa>]
|
88
|
+
# @overload each(path=".", o={})
|
89
|
+
# @yieldparam [Pa] path
|
90
|
+
# @return [nil]
|
91
|
+
def each(*args, &blk)
|
92
|
+
return Pa.to_enum(:each, *args) unless blk
|
93
|
+
|
94
|
+
(path,), o = args.extract_options
|
95
|
+
path = path ? get(path) : "."
|
96
|
+
raise Errno::ENOENT, "`#{path}' doesn't exists." unless File.exists?(path)
|
97
|
+
raise Errno::ENOTDIR, "`#{path}' not a directoyr." unless File.directory?(path)
|
98
|
+
|
99
|
+
begin
|
100
|
+
dir = Dir.open(path)
|
101
|
+
rescue Errno::EPERM => err
|
102
|
+
end
|
103
|
+
raise err if err and !o[:error]
|
104
|
+
|
105
|
+
while (entry=dir.read)
|
106
|
+
next if %w(. ..).include? entry
|
107
|
+
next if o[:nodot] and entry=~/^\./
|
108
|
+
next if o[:nobackup] and entry=~/~$/
|
109
|
+
|
110
|
+
# => "foo" not "./foo"
|
111
|
+
pa = path=="." ? Pa(entry) : Pa(File.join(path, entry))
|
112
|
+
if o[:error]
|
113
|
+
blk.call pa, err
|
114
|
+
else
|
115
|
+
blk.call pa
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# each with recursive
|
121
|
+
# @see each
|
122
|
+
#
|
123
|
+
# * each_r() skip Exception
|
124
|
+
# * each_r(){pa, err}
|
125
|
+
#
|
126
|
+
# @overload each_r(path=".", o={})
|
127
|
+
# @return [Enumerator<Pa>]
|
128
|
+
# @overload each_r(path=".", o={})
|
129
|
+
# @yieldparam [Pa] pa
|
130
|
+
# @yieldparam [String] relative relative path
|
131
|
+
# @yieldparam [Errno::ENOENT,Errno::EPERM] err
|
132
|
+
# @return [nil]
|
133
|
+
def each_r(*args, &blk)
|
134
|
+
return Pa.to_enum(:each_r, *args) if not blk
|
135
|
+
|
136
|
+
(path,), o = args.extract_options
|
137
|
+
path ||= "."
|
138
|
+
|
139
|
+
_each_r(path, "", o, &blk)
|
140
|
+
end
|
141
|
+
|
142
|
+
# @param [String] path
|
143
|
+
def _each_r path, relative, o, &blk
|
144
|
+
o.merge!(error: true)
|
145
|
+
Pa.each(path, o) do |pa1, err|
|
146
|
+
relative1 = Pa.join(relative, pa1.b)
|
147
|
+
|
148
|
+
blk.call pa1, relative1, err
|
149
|
+
|
150
|
+
if pa1.directory?
|
151
|
+
_each_r(pa1.p, relative1, o, &blk)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
private :_each_r
|
156
|
+
|
157
|
+
# list directory contents
|
158
|
+
# @see each
|
159
|
+
#
|
160
|
+
# block form is a filter.
|
161
|
+
#
|
162
|
+
# @Example
|
163
|
+
# Pa.ls(".") {|pa, fname| pa.directory?} # list only directories
|
164
|
+
#
|
165
|
+
# @overload ls(path=".", o={})
|
166
|
+
# @return [Array<String>]
|
167
|
+
# @overload ls(path=".", o={})
|
168
|
+
# @yieldparam [Pa] pa
|
169
|
+
# @yieldparam [String] fname
|
170
|
+
# @return [Array<String>]
|
171
|
+
def ls *args, &blk
|
172
|
+
blk ||= proc {true}
|
173
|
+
each(*args).with_object([]) { |pa,m|
|
174
|
+
m<<pa.fname if blk.call(pa, pa.fname)
|
175
|
+
}
|
176
|
+
end
|
177
|
+
|
178
|
+
# ls with recursive
|
179
|
+
# @see ls
|
180
|
+
#
|
181
|
+
# @overload ls_r(path=".", o={})
|
182
|
+
# @return [Array<String>]
|
183
|
+
# @overload ls_r(path=".", o={})
|
184
|
+
# @yieldparam [Pa] pa
|
185
|
+
# @yieldparam [String] rel
|
186
|
+
# @return [Array<String>]
|
187
|
+
def ls_r *args, &blk
|
188
|
+
blk ||= proc {true}
|
189
|
+
each_r(*args).with_object([]) { |(pa,rel),m|
|
190
|
+
m<<rel if blk.call(pa, rel)
|
191
|
+
}
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
end
|
data/lib/pa/path.rb
ADDED
@@ -0,0 +1,301 @@
|
|
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/pa/state.rb
ADDED
@@ -0,0 +1,67 @@
|
|
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
|
+
|