pa 1.3.0 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.travis.yml +0 -5
- data/CHANGELOG +6 -0
- data/Gemfile.lock +11 -12
- data/README.md +4 -9
- data/lib/pa.rb +191 -193
- data/lib/pa/cmd.rb +18 -9
- data/lib/pa/directory.rb +15 -17
- data/lib/pa/path.rb +126 -76
- data/lib/pa/state.rb +22 -24
- data/lib/pa/util.rb +114 -17
- data/lib/pa/version.rb +1 -1
- data/pa.gemspec +1 -0
- data/pa.watchr +3 -3
- data/spec/data/tmp/.gitkeep +0 -0
- data/spec/pa/cmd_spec.rb +10 -12
- data/spec/pa/directory_spec.rb +6 -11
- data/spec/pa/path_spec.rb +48 -42
- data/spec/pa_spec.rb +168 -155
- data/spec/spec_helper.rb +22 -20
- metadata +5 -7
- data/spec/pa/util_spec.rb +0 -13
data/lib/pa/cmd.rb
CHANGED
@@ -30,8 +30,10 @@ Pa.touch "a b c", :verbose => true
|
|
30
30
|
class Pa
|
31
31
|
module Cmd
|
32
32
|
extend Util::Concern
|
33
|
+
|
34
|
+
DELEGATE_CLASS_METHODS = [ :home ]
|
35
|
+
|
33
36
|
module ClassMethods
|
34
|
-
DELEGATE_METHODS = [ :home ]
|
35
37
|
|
36
38
|
def home2
|
37
39
|
Dir.home
|
@@ -81,7 +83,7 @@ class Pa
|
|
81
83
|
|
82
84
|
# @see File.readlink
|
83
85
|
def readlink(path)
|
84
|
-
File.readlink(get(path))
|
86
|
+
File.readlink(File.absolute_path(get(path), ".")) # jruby rbx
|
85
87
|
end
|
86
88
|
|
87
89
|
# change directory
|
@@ -510,11 +512,13 @@ class Pa
|
|
510
512
|
|
511
513
|
mkdir(File.dirname(p)) if o[:mkdir]
|
512
514
|
|
513
|
-
if Util.
|
514
|
-
#
|
515
|
-
File.open(p, "w"){|f| f.
|
515
|
+
if Util.windows?
|
516
|
+
# windows BUG. must f.write("") then file can be deleted.
|
517
|
+
File.open(p, "w"){|f| f.write("")} # windows need f.write so that it can be delete.
|
518
|
+
File.chmod(o[:mode], p) # jruby can't use File#chmod
|
516
519
|
else
|
517
|
-
File.open(p, "w"){
|
520
|
+
File.open(p, "w"){}
|
521
|
+
File.chmod(o[:mode], p)
|
518
522
|
end
|
519
523
|
}
|
520
524
|
end
|
@@ -544,6 +548,11 @@ class Pa
|
|
544
548
|
|
545
549
|
puts "ln #{extra_doc}#{src} #{dest}" if o[:verbose]
|
546
550
|
|
551
|
+
# jruby need absolute_path
|
552
|
+
if method == :link then
|
553
|
+
src, dest = File.absolute_path(src, "."), File.absolute_path(dest, ".") # rbx
|
554
|
+
end
|
555
|
+
|
547
556
|
File.send(method, src, dest)
|
548
557
|
}
|
549
558
|
end
|
@@ -580,7 +589,7 @@ class Pa
|
|
580
589
|
|
581
590
|
# <name>.JNBNZG
|
582
591
|
def _mktmpname(name=nil, o={})
|
583
|
-
o[:tmpdir] ||=
|
592
|
+
o[:tmpdir] ||= Dir.tmpdir
|
584
593
|
name ||= $$
|
585
594
|
|
586
595
|
begin
|
@@ -647,8 +656,8 @@ class Pa
|
|
647
656
|
end
|
648
657
|
end # _copy
|
649
658
|
|
650
|
-
|
651
|
-
|
659
|
+
DELEGATE_CLASS_METHODS.each do |mth|
|
660
|
+
eval <<-EOF
|
652
661
|
def #{mth}(*args, &blk)
|
653
662
|
Pa(#{mth}2(*args, &blk))
|
654
663
|
end
|
data/lib/pa/directory.rb
CHANGED
@@ -128,7 +128,7 @@ class Pa
|
|
128
128
|
if not File.directory?(rea_dir)
|
129
129
|
if o[:file]
|
130
130
|
rea_path = rea_dir
|
131
|
-
blk.call dir, File.absolute_path(rea_path), File.basename(rea_path), nil, rea_path
|
131
|
+
blk.call dir, File.absolute_path(rea_path, "."), File.basename(rea_path), nil, rea_path # jruby rbx
|
132
132
|
return
|
133
133
|
else
|
134
134
|
raise Errno::ENOTDIR, "`#{rea_dir}' is not a directoy."
|
@@ -146,9 +146,9 @@ class Pa
|
|
146
146
|
next if not o[:dot] and entry=~/^\./
|
147
147
|
next if not o[:backup] and entry=~/~$/
|
148
148
|
|
149
|
-
path = Util.
|
150
|
-
rea_path = Util.
|
151
|
-
blk.call path, File.absolute_path(rea_path), File.basename(rea_path), err, rea_path
|
149
|
+
path = Util.join_path(dir, entry)
|
150
|
+
rea_path = Util.join_path(rea_dir, entry)
|
151
|
+
blk.call path, File.absolute_path(rea_path, "."), File.basename(rea_path), err, rea_path # jruby rbx
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
@@ -157,7 +157,7 @@ class Pa
|
|
157
157
|
|
158
158
|
args, o = Util.extract_options(args)
|
159
159
|
each2(*args, o) { |path, abs, fname, err, rea|
|
160
|
-
blk.call Pa(path), abs, fname, err, rea
|
160
|
+
blk.call Pa(path), abs, fname, err, rea # jruby need []
|
161
161
|
}
|
162
162
|
end
|
163
163
|
|
@@ -190,7 +190,7 @@ class Pa
|
|
190
190
|
|
191
191
|
args, o = Util.extract_options(args)
|
192
192
|
each2_r *args, o do |path, abs, rel, err, rea|
|
193
|
-
blk.call Pa(path, :rel => rel), abs, rel, err, rea
|
193
|
+
blk.call Pa(path, :rel => rel), abs, rel, err, rea # jruby need []
|
194
194
|
end
|
195
195
|
end
|
196
196
|
|
@@ -312,7 +312,7 @@ class Pa
|
|
312
312
|
rel = File.join(*[relative, File.basename(path2)].compact)
|
313
313
|
rea = o[:base_dir] ? File.join(get(o[:base_dir]), rel) : rel
|
314
314
|
|
315
|
-
blk.call path2, abs, rel, err, rea
|
315
|
+
blk.call path2, abs, rel, err, rea # jruby need []
|
316
316
|
|
317
317
|
if File.directory?(abs)
|
318
318
|
_each2_r(path2, rel, o, &blk)
|
@@ -321,16 +321,14 @@ class Pa
|
|
321
321
|
end
|
322
322
|
end
|
323
323
|
|
324
|
-
|
325
|
-
DELEGATE_METHODS = [:each2, :each, :each2_r, :each_r, :ls2, :ls]
|
324
|
+
DELEGATE_METHODS = [:each2, :each, :each2_r, :each_r, :ls2, :ls]
|
326
325
|
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
end
|
326
|
+
DELEGATE_METHODS.each { |mth|
|
327
|
+
class_eval <<-EOF
|
328
|
+
def #{mth}(*args, &blk)
|
329
|
+
Pa.#{mth}(path, *args, &blk)
|
330
|
+
end
|
331
|
+
EOF
|
332
|
+
}
|
335
333
|
end
|
336
334
|
end
|
data/lib/pa/path.rb
CHANGED
@@ -15,102 +15,140 @@ class Pa
|
|
15
15
|
module Path
|
16
16
|
extend Util::Concern
|
17
17
|
|
18
|
+
DELEGATE_CLASS_METHODS = [:pwd, :dir, :expand, :real, :parent,
|
19
|
+
:relative_to, :shorten, :delete_ext, :add_ext ]
|
20
|
+
|
18
21
|
module ClassMethods
|
19
|
-
DELEGATE_METHODS = [:pwd, :dir, :absolute, :expand, :real, :parent]
|
20
22
|
|
21
|
-
#
|
23
|
+
# Return current work directory
|
24
|
+
#
|
22
25
|
# @return [String] path
|
23
26
|
def pwd2
|
24
27
|
Dir.getwd
|
25
28
|
end
|
26
29
|
|
27
|
-
#
|
30
|
+
# Is path an absolute path ?
|
28
31
|
#
|
29
32
|
# @param [String,Pa] path
|
30
33
|
# @return [Boolean]
|
31
34
|
def absolute?(path)
|
32
|
-
|
33
|
-
File.absolute_path(
|
35
|
+
p = get(path)
|
36
|
+
File.absolute_path(p, ".") == p # rbx
|
34
37
|
end
|
35
38
|
|
36
|
-
#
|
39
|
+
# Is path a dangling symlink?
|
37
40
|
#
|
38
41
|
# a dangling symlink is a dead symlink.
|
39
42
|
#
|
40
43
|
# @param [String,Pa] path
|
41
44
|
# @return [Boolean]
|
42
|
-
def dangling?
|
43
|
-
|
44
|
-
|
45
|
-
|
45
|
+
def dangling?(path)
|
46
|
+
p = get(path)
|
47
|
+
|
48
|
+
if File.symlink?(p)
|
49
|
+
src = File.readlink(p)
|
46
50
|
not File.exists?(src)
|
47
51
|
else
|
48
52
|
nil
|
49
53
|
end
|
50
|
-
end
|
54
|
+
end
|
51
55
|
|
52
|
-
|
53
|
-
|
56
|
+
# Alias from File.expand_path
|
57
|
+
#
|
58
|
+
# @param [String,Pa] path
|
59
|
+
# @return [String]
|
60
|
+
def expand2(path)
|
61
|
+
File.expand_path get(path)
|
54
62
|
end
|
55
63
|
|
56
|
-
#
|
64
|
+
# Path relative_to? dir
|
57
65
|
#
|
58
66
|
# @example
|
59
|
-
# Pa.basename("foo.bar.c", ext: true) #=> \["foo.bar", "c"]
|
60
67
|
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
[
|
72
|
-
|
73
|
-
name
|
74
|
-
end
|
68
|
+
# Pa.relative_to?("/home/foo", "/home") -> true
|
69
|
+
# Pa.relative_to?("/home1/foo", "/home") -> false
|
70
|
+
#
|
71
|
+
def relative_to?(path, dir)
|
72
|
+
path_parts = Pa.split2(get(path), all: true)
|
73
|
+
dir_parts = Pa.split2(get(dir), all: true)
|
74
|
+
|
75
|
+
index = -1
|
76
|
+
dir_parts.all? {|part|
|
77
|
+
index += 1
|
78
|
+
path_parts[index] == part
|
79
|
+
}
|
75
80
|
end
|
76
81
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
+
# Delete the head.
|
83
|
+
#
|
84
|
+
# @example
|
85
|
+
#
|
86
|
+
# Pa.relative_to2("/home/foo", "/home") -> "foo"
|
87
|
+
# Pa.relative_to2("/home/foo", "/home/foo") -> "."
|
88
|
+
# Pa.relative_to2("/home/foo", "/bin") -> "/home/foo"
|
89
|
+
#
|
90
|
+
# Pa.relative_to2("/home/foo", "/home/foo/") -> "."
|
91
|
+
# Pa.relative_to2("/home/foo/", "/home/foo") -> "."
|
92
|
+
#
|
93
|
+
# @return [String]
|
94
|
+
def relative_to2(path, dir)
|
95
|
+
p = get(path)
|
96
|
+
|
97
|
+
if relative_to?(p, dir)
|
98
|
+
path_parts = Pa.split(p, all: true)
|
99
|
+
dir_parts = Pa.split(dir, all: true)
|
100
|
+
ret = File.join(*path_parts[dir_parts.length..-1])
|
101
|
+
ret == "" ? "." : ret
|
82
102
|
else
|
83
|
-
|
103
|
+
p
|
84
104
|
end
|
85
105
|
end
|
86
106
|
|
87
|
-
#
|
107
|
+
# Return true if a path has the ext.
|
88
108
|
#
|
89
109
|
# @example
|
90
|
-
# "a.ogg" => "ogg"
|
91
|
-
# "a" => nil
|
92
110
|
#
|
93
|
-
#
|
94
|
-
#
|
95
|
-
|
96
|
-
|
97
|
-
ext
|
111
|
+
# Pa.has_ext?("foo.txt", ".txt") -> true
|
112
|
+
# Pa.has_ext?("foo", ".txt") -> false
|
113
|
+
#
|
114
|
+
def has_ext?(path, ext)
|
115
|
+
Pa.ext2(get(path)) == ext
|
98
116
|
end
|
99
117
|
|
100
|
-
|
118
|
+
# Delete the tail.
|
119
|
+
#
|
120
|
+
# @example
|
121
|
+
#
|
122
|
+
# Pa.delete_ext2("foo.txt", ".txt") -> "foo"
|
123
|
+
# Pa.delete_ext2("foo", ".txt") -> "foo"
|
124
|
+
# Pa.delete_ext2("foo.epub", ".txt") -> "foo.epub"
|
125
|
+
#
|
126
|
+
def delete_ext2(path, ext)
|
127
|
+
p = get(path)
|
101
128
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
129
|
+
if has_ext?(p, ext)
|
130
|
+
p[0...p.rindex(ext)]
|
131
|
+
else
|
132
|
+
p
|
133
|
+
end
|
107
134
|
end
|
108
135
|
|
109
|
-
#
|
110
|
-
#
|
111
|
-
# @
|
112
|
-
|
113
|
-
|
136
|
+
# Ensure the tail
|
137
|
+
#
|
138
|
+
# @example
|
139
|
+
#
|
140
|
+
# Pa.add_ext2("foo", ".txt") -> "foo.txt"
|
141
|
+
# Pa.add_ext2("foo.txt", ".txt") -> "foo.txt"
|
142
|
+
# Pa.add_ext2("foo.epub", ".txt") -> "foo.txt.epub"
|
143
|
+
#
|
144
|
+
def add_ext2(path, ext)
|
145
|
+
p = get(path)
|
146
|
+
|
147
|
+
if Pa.ext2(p) == ext
|
148
|
+
p
|
149
|
+
else
|
150
|
+
"#{p}#{ext}"
|
151
|
+
end
|
114
152
|
end
|
115
153
|
|
116
154
|
# shorten2 a path,
|
@@ -119,10 +157,20 @@ class Pa
|
|
119
157
|
# @param [String,Pa] path
|
120
158
|
# @return [String]
|
121
159
|
def shorten2(path)
|
122
|
-
get(path)
|
123
|
-
|
160
|
+
p = get(path)
|
161
|
+
home = Pa.home2
|
124
162
|
|
125
|
-
|
163
|
+
return p if home.empty?
|
164
|
+
|
165
|
+
ret = relative_to2(p, home)
|
166
|
+
|
167
|
+
if ret == p
|
168
|
+
p
|
169
|
+
else
|
170
|
+
ret == "." ? "" : ret
|
171
|
+
File.join("~", ret)
|
172
|
+
end
|
173
|
+
end
|
126
174
|
|
127
175
|
# real path
|
128
176
|
def real2(path)
|
@@ -142,36 +190,38 @@ class Pa
|
|
142
190
|
path
|
143
191
|
end
|
144
192
|
|
145
|
-
|
193
|
+
DELEGATE_CLASS_METHODS.each { |mth|
|
146
194
|
mth2 = "#{mth}2"
|
147
195
|
|
148
|
-
|
196
|
+
eval <<-EOF
|
149
197
|
def #{mth}(*args, &blk)
|
150
198
|
Pa(Pa.#{mth2}(*args, &blk))
|
151
199
|
end
|
152
200
|
EOF
|
153
201
|
}
|
202
|
+
|
203
|
+
|
204
|
+
private
|
205
|
+
|
154
206
|
end
|
155
207
|
|
156
|
-
|
157
|
-
|
158
|
-
DELEGATE_METHODS = [ :parent]
|
208
|
+
DELEGATE_METHODS2 = [ :parent2 ]
|
209
|
+
DELEGATE_METHODS = [ :parent]
|
159
210
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
211
|
+
DELEGATE_METHODS2.each do |mth2|
|
212
|
+
class_eval <<-EOF
|
213
|
+
def #{mth2}(*args, &blk)
|
214
|
+
Pa.#{mth2}(path, *args, &blk)
|
215
|
+
end
|
216
|
+
EOF
|
217
|
+
end
|
167
218
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
end
|
219
|
+
DELEGATE_METHODS.each do |mth|
|
220
|
+
class_eval <<-EOF
|
221
|
+
def #{mth}(*args, &blk)
|
222
|
+
Pa(#{mth}2(*args, &blk))
|
223
|
+
end
|
224
|
+
EOF
|
175
225
|
end
|
176
226
|
end
|
177
227
|
end
|
data/lib/pa/state.rb
CHANGED
@@ -80,35 +80,33 @@ class Pa
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
}
|
83
|
+
# delegated from File
|
84
|
+
FILE_DELEGATED_METHODS.each { |name|
|
85
|
+
module_eval <<-METHOD, __FILE__, __LINE__
|
86
|
+
def #{name}(*args)
|
87
|
+
File.#{name}(*args, path)
|
88
|
+
end
|
89
|
+
METHOD
|
90
|
+
}
|
92
91
|
|
93
|
-
|
94
|
-
|
95
|
-
|
92
|
+
def chmod(mode)
|
93
|
+
File.chmod(mode, path)
|
94
|
+
end
|
96
95
|
|
97
|
-
|
98
|
-
|
99
|
-
|
96
|
+
def lchmod(mode)
|
97
|
+
File.lchmod(mode, path)
|
98
|
+
end
|
100
99
|
|
101
|
-
|
102
|
-
|
103
|
-
|
100
|
+
def chown(uid, gid=nil)
|
101
|
+
File.chown(uid, gid, path)
|
102
|
+
end
|
104
103
|
|
105
|
-
|
106
|
-
|
107
|
-
|
104
|
+
def lchown(uid, gid=nil)
|
105
|
+
File.lchown(uid, gid, path)
|
106
|
+
end
|
108
107
|
|
109
|
-
|
110
|
-
|
111
|
-
end
|
108
|
+
def utime(atime, mtime)
|
109
|
+
File.utime(atime, mtime, path)
|
112
110
|
end
|
113
111
|
end
|
114
112
|
end
|