tagen 0.2.1 → 0.2.3
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/README.md +36 -1
- data/Rakefile +8 -1
- data/TODO +1 -0
- data/lib/tagen/audioinfo.rb +1 -0
- data/lib/tagen/cairo.rb +2 -0
- data/lib/tagen/core.rb +2 -0
- data/lib/tagen/core/array.rb +58 -0
- data/lib/tagen/core/enumerable.rb +20 -0
- data/lib/tagen/core/enumerator.rb +29 -0
- data/lib/tagen/core/module.rb +5 -4
- data/lib/tagen/core/pa.rb +53 -75
- data/lib/tagen/core/pa/cmd.rb +59 -52
- data/lib/tagen/core/pa/dir.rb +41 -20
- data/lib/tagen/core/pa/path.rb +132 -31
- data/lib/tagen/core/pa/state.rb +17 -6
- data/lib/tagen/core/string/pyformat.rb +2 -2
- data/lib/tagen/erb.rb +35 -0
- data/lib/tagen/magick.rb +1 -0
- data/lib/tagen/ncurses.rb +1 -0
- data/lib/tagen/pathname.rb +1 -0
- data/lib/tagen/poppler.rb +1 -0
- data/lib/tagen/socket.rb +2 -0
- data/lib/tagen/tree.rb +2 -0
- data/lib/tagen/xmpp4r.rb +1 -0
- data/lib/tagen/yaml.rb +36 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/tagen/core/array_spec.rb +37 -0
- data/spec/tagen/core/enumerator_spec.rb +21 -0
- data/spec/tagen/core/pa/cmd_spec.rb +17 -14
- data/spec/tagen/core/pa/dir_spec.rb +20 -5
- data/spec/tagen/core/pa/path_spec.rb +117 -0
- data/spec/tagen/core/pa/state_spec.rb +7 -0
- data/spec/tagen/erb_spec.rb +19 -0
- data/spec/tagen/yaml_spec.rb +32 -0
- data/version.rb +1 -1
- metadata +13 -2
data/lib/tagen/core/pa/dir.rb
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
each(".").with_index(2){|pa,i| ... }
|
13
13
|
=end
|
14
14
|
class Pa
|
15
|
-
module
|
15
|
+
module ClassMethods::Dir
|
16
16
|
|
17
17
|
# path globbing, exclude '.' '..' for :dotmatch
|
18
18
|
# @note glob is * ** ? [set] {a,b}
|
@@ -58,7 +58,7 @@ module Directory
|
|
58
58
|
def empty?(path) Dir.entries(get(path)).empty? end
|
59
59
|
|
60
60
|
# traverse directory
|
61
|
-
# @note
|
61
|
+
# @note raise Errno::ENOTDIR, Errno::ENOENT
|
62
62
|
#
|
63
63
|
# @example
|
64
64
|
# each '.' do |pa|
|
@@ -66,29 +66,46 @@ module Directory
|
|
66
66
|
# end
|
67
67
|
# # => '/home' ..
|
68
68
|
#
|
69
|
+
# each('.', error: true).with_object([]) do |(pa,err),m|
|
70
|
+
# ...
|
71
|
+
# end
|
72
|
+
#
|
69
73
|
# @overload each(path=".", o={})
|
70
74
|
# @param [String,Pa] path
|
71
75
|
# @prarm [Hash] o
|
72
|
-
# @option o [Boolean] :nodot (
|
73
|
-
# @option o [Boolean] :nobackup (
|
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)
|
74
79
|
# @return [Enumerator<Pa>]
|
75
80
|
# @overload each(path=".", o={})
|
76
81
|
# @yieldparam [Pa] path
|
77
82
|
# @return [nil]
|
78
83
|
def each(*args, &blk)
|
79
|
-
return Pa.to_enum(:each, *args)
|
84
|
+
return Pa.to_enum(:each, *args) unless blk
|
80
85
|
|
81
86
|
(path,), o = args.extract_options
|
82
|
-
|
83
|
-
|
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]
|
84
96
|
|
85
|
-
|
86
|
-
next if %w(. ..).include?
|
87
|
-
next if o[:nodot] and
|
88
|
-
next if o[:nobackup] and
|
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=~/~$/
|
89
101
|
|
90
102
|
# => "foo" not "./foo"
|
91
|
-
|
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
|
92
109
|
end
|
93
110
|
end
|
94
111
|
|
@@ -101,7 +118,9 @@ module Directory
|
|
101
118
|
# @overload each_r(path=".", o={})
|
102
119
|
# @return [Enumerator<Pa>]
|
103
120
|
# @overload each_r(path=".", o={})
|
104
|
-
# @
|
121
|
+
# @yieldparam [Pa] pa
|
122
|
+
# @yieldparam [String] relative relative path
|
123
|
+
# @yieldparam [Errno::ENOENT,Errno::EPERM] err
|
105
124
|
# @return [nil]
|
106
125
|
def each_r(*args, &blk)
|
107
126
|
return Pa.to_enum(:each_r, *args) if not blk
|
@@ -109,19 +128,21 @@ module Directory
|
|
109
128
|
(path,), o = args.extract_options
|
110
129
|
path ||= "."
|
111
130
|
|
112
|
-
_each_r(
|
131
|
+
_each_r(path, "", o, &blk)
|
113
132
|
end
|
114
133
|
|
115
|
-
|
116
|
-
|
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|
|
117
138
|
relative1 = Pa.join(relative, pa1.b)
|
118
|
-
|
139
|
+
|
140
|
+
blk.call pa1, relative1, err
|
141
|
+
|
119
142
|
if pa1.directory?
|
120
|
-
_each_r(pa1, relative1, o, &blk)
|
143
|
+
_each_r(pa1.p, relative1, o, &blk)
|
121
144
|
end
|
122
145
|
end
|
123
|
-
rescue Errno::ENOENT, Errno::EPERM => e
|
124
|
-
blk.call pa, relative, e
|
125
146
|
end
|
126
147
|
private :_each_r
|
127
148
|
|
data/lib/tagen/core/pa/path.rb
CHANGED
@@ -1,37 +1,47 @@
|
|
1
1
|
class Pa
|
2
|
-
|
2
|
+
NAME_EXT_PAT = /^(.+?)(?:\.([^.]+))?$/
|
3
|
+
module ClassMethods::Path
|
3
4
|
|
4
5
|
# alias from File.absolute_path
|
5
|
-
# @param [String] path
|
6
|
+
# @param [String,Pa] path
|
6
7
|
# @return [String]
|
7
8
|
def absolute(path); File.absolute_path(get(path)) end
|
8
9
|
|
9
10
|
# alias from File.expand_path
|
10
|
-
# @param [String] path
|
11
|
+
# @param [String,Pa] path
|
11
12
|
# @return [String]
|
12
13
|
def expand(path); File.expand_path(get(path)) end
|
13
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
|
+
|
14
24
|
# print current work directory
|
15
25
|
# @return [String] path
|
16
26
|
def pwd() Dir.getwd end
|
17
27
|
|
18
28
|
# change directory
|
19
29
|
#
|
20
|
-
# @param [String] path
|
30
|
+
# @param [String,Pa] path
|
21
31
|
def cd(path=ENV["HOME"], &blk) Dir.chdir(get(path), &blk) end
|
22
32
|
|
23
33
|
# get path of an object.
|
24
34
|
#
|
25
35
|
# return obj#path if object has a 'path' instance method
|
26
36
|
#
|
27
|
-
# @param [String
|
37
|
+
# @param [String,#path] obj
|
28
38
|
# @return [String,nil] path
|
29
39
|
def get obj
|
30
|
-
|
31
|
-
|
32
|
-
begin
|
40
|
+
if obj.respond_to?(:path)
|
33
41
|
obj.path
|
34
|
-
|
42
|
+
elsif String === obj
|
43
|
+
obj
|
44
|
+
else
|
35
45
|
raise Error, "not support type -- #{obj.inspect}(#{obj.class})"
|
36
46
|
end
|
37
47
|
end
|
@@ -42,7 +52,7 @@ class Pa
|
|
42
52
|
# "a.ogg" => "ogg"
|
43
53
|
# "a" => nil
|
44
54
|
#
|
45
|
-
# @param [String] path
|
55
|
+
# @param [String,Pa] path
|
46
56
|
# @return [String]
|
47
57
|
def extname path
|
48
58
|
_, ext = get(path).match(/\.([^.]+)$/).to_a
|
@@ -51,22 +61,25 @@ class Pa
|
|
51
61
|
|
52
62
|
# is path an absolute path ?
|
53
63
|
#
|
54
|
-
# @param [String] path
|
64
|
+
# @param [String,Pa] path
|
55
65
|
# @return [Boolean]
|
56
|
-
def absolute?(path)
|
66
|
+
def absolute?(path) path=get(path); File.absolute_path(path) == path end
|
57
67
|
|
58
68
|
# get a basename of a path
|
59
69
|
#
|
60
|
-
# @
|
70
|
+
# @example
|
71
|
+
# Pa.basename("foo.bar.c", ext: true) #=> \["foo.bar", "c"]
|
72
|
+
#
|
73
|
+
# @param [String,Pa] name
|
61
74
|
# @param [Hash] o options
|
62
75
|
# @option o [Boolean, String] :ext (false) return \[name, ext] if true
|
63
76
|
#
|
64
|
-
# @return [String] basename of a path
|
65
|
-
# @return [Array<String
|
77
|
+
# @return [String] basename of a path unless o[:ext]
|
78
|
+
# @return [Array<String>] \[name, ext] if o[:ext].
|
66
79
|
def basename(name, o={})
|
67
80
|
name = File.basename(get(name))
|
68
81
|
if o[:ext]
|
69
|
-
|
82
|
+
name, ext = name.match(NAME_EXT_PAT).captures
|
70
83
|
[ name, (ext || "")]
|
71
84
|
else
|
72
85
|
name
|
@@ -80,7 +93,7 @@ class Pa
|
|
80
93
|
# split(path) #=> "/home/a", "file"
|
81
94
|
# split(path, :all) #=> "/", "home", "a", "file"
|
82
95
|
#
|
83
|
-
# @param [String] name
|
96
|
+
# @param [String,Pa] name
|
84
97
|
# @param [Hash] o option
|
85
98
|
# @option o [Boolean] :all split all parts
|
86
99
|
# @return [Array<String>]
|
@@ -118,10 +131,15 @@ class Pa
|
|
118
131
|
|
119
132
|
# get parent path
|
120
133
|
#
|
121
|
-
# @param [String] path
|
134
|
+
# @param [String,Pa] path
|
135
|
+
# @param [Fixnum] n up level
|
122
136
|
# @return [String]
|
123
|
-
def parent path
|
124
|
-
|
137
|
+
def parent path, n=1
|
138
|
+
path = get(path)
|
139
|
+
n.times do
|
140
|
+
path = File.dirname(path)
|
141
|
+
end
|
142
|
+
path
|
125
143
|
end
|
126
144
|
|
127
145
|
# link
|
@@ -130,7 +148,7 @@ class Pa
|
|
130
148
|
# @overload ln([src,..], directory)
|
131
149
|
#
|
132
150
|
# @param [Array<String>, String] src_s support globbing
|
133
|
-
# @param [String] dest
|
151
|
+
# @param [String,Pa] dest
|
134
152
|
# @param [Hash] o option
|
135
153
|
# @option o [Boolean] :force overwrite if exists.
|
136
154
|
# @return [nil]
|
@@ -155,13 +173,15 @@ class Pa
|
|
155
173
|
# @return [nil]
|
156
174
|
def symln_f(src_s, dest, o) o[:force]=true; _ln(File.method(:symlink), src_s, dest, o) end
|
157
175
|
|
158
|
-
# param
|
176
|
+
# @param [Array,String,#path] src_s
|
177
|
+
# @param [String,#path] dest
|
159
178
|
def _ln(method, src_s, dest, o={})
|
160
|
-
dest =
|
179
|
+
dest = get(dest)
|
161
180
|
glob(*Array.wrap(src_s)) {|src|
|
162
|
-
|
163
|
-
|
164
|
-
|
181
|
+
src = get(src)
|
182
|
+
dest = File.join(dest, File.basename(src)) if File.directory?(dest)
|
183
|
+
Pa.rm_r(dest) if o[:force] and File.exists?(dest)
|
184
|
+
method.call(src, dest)
|
165
185
|
}
|
166
186
|
end
|
167
187
|
private :_ln
|
@@ -169,22 +189,103 @@ class Pa
|
|
169
189
|
# @see File.readlink
|
170
190
|
def readlink(path) File.readlink(get(path)) end
|
171
191
|
|
172
|
-
|
173
192
|
# is path a dangling symlink?
|
174
193
|
#
|
175
194
|
# a dangling symlink is a dead symlink.
|
176
195
|
#
|
177
|
-
# @param [String] path
|
196
|
+
# @param [String,Pa] path
|
178
197
|
# @return [Boolean]
|
179
198
|
def dangling? path
|
180
199
|
path=get(path)
|
181
|
-
if symlink?(path)
|
182
|
-
src = readlink(path)
|
183
|
-
not exists?(src)
|
200
|
+
if File.symlink?(path)
|
201
|
+
src = File.readlink(path)
|
202
|
+
not File.exists?(src)
|
184
203
|
else
|
185
204
|
nil
|
186
205
|
end
|
187
206
|
end # def dsymlink?
|
188
207
|
|
208
|
+
def realpath(path) File.realpath(get(path)) end
|
209
|
+
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
class Pa
|
214
|
+
=begin
|
215
|
+
|
216
|
+
attribute absolute and dir return String, method absolute_path(), dirname() return Pa
|
217
|
+
|
218
|
+
Pa("/home/a").dir #=> "/home"
|
219
|
+
Pa("/home/a").dirname #=> Pa("/home")
|
220
|
+
|
221
|
+
== methods from String
|
222
|
+
* +
|
223
|
+
* [g]sub[!] match =~
|
224
|
+
* start_with? end_with?
|
225
|
+
|
226
|
+
=end
|
227
|
+
module Path
|
228
|
+
# @return [String]
|
229
|
+
attr_reader :absolute, :dir, :base, :name, :ext, :fext, :short
|
230
|
+
|
231
|
+
def initialize_variables
|
232
|
+
super
|
233
|
+
@absolute = Pa.absolute(@path)
|
234
|
+
@dir = Pa.dirname(@path)
|
235
|
+
@base = Pa.basename(@path)
|
236
|
+
@name, @ext = Pa.basename(@path, ext: true)
|
237
|
+
@fext = @ext.empty? ? "" : "."+@ext
|
238
|
+
@short = Pa.shorten(@path)
|
239
|
+
end
|
240
|
+
|
241
|
+
alias a absolute
|
242
|
+
alias d dir
|
243
|
+
alias b base
|
244
|
+
alias n name
|
245
|
+
alias e ext
|
246
|
+
alias fe fext
|
247
|
+
|
248
|
+
# @return [Pa] absolute path
|
249
|
+
def absolute_path() Pa(absolute) end
|
250
|
+
# @return [Pa] dirname
|
251
|
+
# @example
|
252
|
+
# Pa(__FILE__).dirname.join('.opts')
|
253
|
+
def dirname() Pa(dir) end
|
254
|
+
|
255
|
+
# add string to path
|
256
|
+
#
|
257
|
+
# @example
|
258
|
+
# pa = Pa('/home/foo/a.txt')
|
259
|
+
# pa+'~' #=> new Pa('/home/foo/a.txt~')
|
260
|
+
#
|
261
|
+
# @param [String] str
|
262
|
+
# @return [Pa]
|
263
|
+
def +(str) Pa(path+str) end
|
264
|
+
|
265
|
+
# @return [Pa]
|
266
|
+
def sub(*args,&blk) Pa(path.sub(*args,&blk)) end
|
267
|
+
|
268
|
+
# @return [Pa]
|
269
|
+
def gsub(*args,&blk) Pa(path.gsub(*args,&blk)) end
|
270
|
+
|
271
|
+
# @return [Pa]
|
272
|
+
def sub!(*args,&blk) self.replace path.sub(*args,&blk) end
|
273
|
+
|
274
|
+
# @return [Pa]
|
275
|
+
def gsub!(*args,&blk) self.replace path.gsub(*args,&blk) end
|
276
|
+
|
277
|
+
# @return [MatchData]
|
278
|
+
def match(*args,&blk) path.match(*args,&blk) end
|
279
|
+
|
280
|
+
# @return [Boolean]
|
281
|
+
def start_with?(*args) path.start_with?(*args) end
|
282
|
+
|
283
|
+
# @return [Boolean]
|
284
|
+
def end_with?(*args) path.end_with?(*args) end
|
285
|
+
|
286
|
+
def =~(regexp) path =~ regexp end
|
287
|
+
|
288
|
+
def ==(other) self.path == other.path end
|
189
289
|
end
|
190
290
|
end
|
291
|
+
|
data/lib/tagen/core/pa/state.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class Pa
|
2
|
-
module State
|
2
|
+
module ClassMethods::State
|
3
3
|
|
4
4
|
# @see File.chmod
|
5
5
|
def chmod(mode, *paths) paths.map!{|v|get(v)}; File.chmod(mode, *paths) end
|
@@ -8,10 +8,10 @@ module State
|
|
8
8
|
def lchmod(mode, *paths) paths.map!{|v|get(v)}; File.lchmod(mode, *paths) end
|
9
9
|
|
10
10
|
# @see File.chown
|
11
|
-
def chown(user, group, *paths) paths.map!{|v|get(v)}; File.chown(user, group, *paths) end
|
11
|
+
def chown(user, group=nil, *paths) paths.map!{|v|get(v)}; File.chown(user, group, *paths) end
|
12
12
|
|
13
13
|
# @see File.lchown
|
14
|
-
def lchown(user, group, *paths) paths.map!{|v|get(v)}; File.lchown(user, group, *paths) end
|
14
|
+
def lchown(user, group=nil, *paths) paths.map!{|v|get(v)}; File.lchown(user, group, *paths) end
|
15
15
|
|
16
16
|
# @see File.utime
|
17
17
|
def utime(atime, mtime, *paths) paths.map!{|v|get(v)}; File.utime(atime, mtime, *paths) end
|
@@ -25,7 +25,7 @@ module State
|
|
25
25
|
# @param [String] path
|
26
26
|
# @return [String]
|
27
27
|
def type(path)
|
28
|
-
case (t=ftype(get(path)))
|
28
|
+
case (t=File.ftype(get(path)))
|
29
29
|
when "characterSpecial"
|
30
30
|
"chardev"
|
31
31
|
when "blockSpecial"
|
@@ -45,12 +45,23 @@ module State
|
|
45
45
|
def mountpoint? path
|
46
46
|
path=get(path)
|
47
47
|
begin
|
48
|
-
stat1 =
|
49
|
-
stat2 =
|
48
|
+
stat1 = File.lstat(path)
|
49
|
+
stat2 = File.lstat(File.join(path, '..'))
|
50
50
|
stat1.dev == stat2.dev && stat1.ino == stat2.ino || stat1.dev != stat2.dev
|
51
51
|
rescue Errno::ENOENT
|
52
52
|
false
|
53
53
|
end
|
54
54
|
end
|
55
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
|
56
63
|
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
|
@@ -11,12 +11,12 @@ a python like string format libraray.
|
|
11
11
|
use "#{var}" is easy and quick in many cases, but some times we need a more powerful format support.
|
12
12
|
|
13
13
|
"I like %s and %s" % %(apple, football)
|
14
|
-
"I like %{fruit} and %{sport}".format(
|
14
|
+
"I like %{fruit} and %{sport}".format('apple', 'football') # it has semantic meaning.
|
15
15
|
|
16
16
|
== Usage
|
17
17
|
|
18
18
|
require "tagen/core"
|
19
|
-
"it costs %{:.2f}
|
19
|
+
"it costs %{:.2f} dollars".format(1.123) #=> "it costs 1.12 dollars"
|
20
20
|
|
21
21
|
* support abritry-argument or hash-argument
|
22
22
|
"%{} %{}".format(1,2) #=> "1 2"
|
data/lib/tagen/erb.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
class ERB
|
4
|
+
alias original_result result
|
5
|
+
|
6
|
+
# add locals support
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# erb = Erb.new("<%=a%>")
|
10
|
+
# erb.result(nil, a: 1) #=> "1"
|
11
|
+
#
|
12
|
+
def result bind=nil, locals={}
|
13
|
+
bind ||= TOPLEVEL_BINDING
|
14
|
+
if locals.empty?
|
15
|
+
original_result bind
|
16
|
+
else
|
17
|
+
result_with_locals bind, locals
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def result_with_locals bind, locals
|
23
|
+
@locals = locals
|
24
|
+
evalstr = <<-EOF
|
25
|
+
def run_erb
|
26
|
+
#{locals.map{|k,v| "#{k} = @locals[:#{k}]"}.join(';')}
|
27
|
+
#{self.src}
|
28
|
+
_erbout
|
29
|
+
end
|
30
|
+
EOF
|
31
|
+
eval evalstr
|
32
|
+
run_erb
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|