tagen 0.2.1 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,7 +12,7 @@
12
12
  each(".").with_index(2){|pa,i| ... }
13
13
  =end
14
14
  class Pa
15
- module Directory
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 return if not a directory.
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 (nil) include dot file
73
- # @option o [Boolean] :nobackup (nil) include backup file
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) if not blk
84
+ return Pa.to_enum(:each, *args) unless blk
80
85
 
81
86
  (path,), o = args.extract_options
82
- pa = Pa(path || ".")
83
- return if not pa.directory?
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
- Dir.foreach pa.p do |name|
86
- next if %w(. ..).include? name
87
- next if o[:nodot] and name=~/^\./
88
- next if o[:nobackup] and name=~/~$/
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
- blk.call pa.p=="." ? Pa(name) : pa.join(name)
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
- # @yield [pa,err]
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(Pa(path), "", o, &blk)
131
+ _each_r(path, "", o, &blk)
113
132
  end
114
133
 
115
- def _each_r pa, relative, o, &blk
116
- each(pa, o) do |pa1|
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
- blk.call pa1, relative1
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
 
@@ -1,37 +1,47 @@
1
1
  class Pa
2
- module Path
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,Pa] obj
37
+ # @param [String,#path] obj
28
38
  # @return [String,nil] path
29
39
  def get obj
30
- return obj if String === obj
31
-
32
- begin
40
+ if obj.respond_to?(:path)
33
41
  obj.path
34
- rescue NoMethodError
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) absolute(path) == get(path) end
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
- # @param [String] name
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,String>] \[name, ext] if o[:ext] is true
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
- _, name, ext = name.match(/^(.+?)(\.[^.]+)?$/).to_a
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
- join(get(path), "..")
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 = Pa(dest)
179
+ dest = get(dest)
161
180
  glob(*Array.wrap(src_s)) {|src|
162
- dest = dest.join(src.b) if dest.directory?
163
- rm_r(dest) if o[:force] and dest.exists?
164
- method.call(src.p, dest.p)
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
+
@@ -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 = path.lstat
49
- stat2 = path.parent.lstat
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(%w(apple football)) # it has semantic meaning.
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} dollar".format(1.123) #=> "it costs 1.12 dollar"
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"
@@ -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