alib 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/a.rb +1 -0
- data/alib-0.4.0.gem +0 -0
- data/b.rb +1 -0
- data/build +0 -0
- data/gemspec.rb +23 -0
- data/install +143 -0
- data/install.rb +143 -0
- data/lib/alib-0.4.0.rb +104 -0
- data/lib/alib-0.4.0/autohash.rb +11 -0
- data/lib/alib-0.4.0/bsearch.rb +255 -0
- data/lib/alib-0.4.0/configfile.rb +113 -0
- data/lib/alib-0.4.0/find2.rb +294 -0
- data/lib/alib-0.4.0/listfile.rb +42 -0
- data/lib/alib-0.4.0/logging.rb +152 -0
- data/lib/alib-0.4.0/main.rb +594 -0
- data/lib/alib-0.4.0/open4.rb +175 -0
- data/lib/alib-0.4.0/orderedautohash.rb +23 -0
- data/lib/alib-0.4.0/orderedhash.rb +243 -0
- data/lib/alib-0.4.0/util.rb +1167 -0
- data/lib/alib.rb +63 -3831
- metadata +23 -3
- data/lib/alib-0.3.1.rb +0 -3872
@@ -0,0 +1,113 @@
|
|
1
|
+
#
|
2
|
+
# yaml configfile class
|
3
|
+
#
|
4
|
+
class ALib::ConfigFile < ::Hash
|
5
|
+
#--{{{
|
6
|
+
DEFAULT_CONIFG = {}
|
7
|
+
DEFAULT_SEARCH_PATH = %w(. ~ /usr/local/etc /usr/etc /etc)
|
8
|
+
DEFAULT_BASENAME = ".#{ File::basename $0 }.conf"
|
9
|
+
|
10
|
+
class << self
|
11
|
+
#--{{{
|
12
|
+
attr :config, true
|
13
|
+
attr :search_path, true
|
14
|
+
attr :basename, true
|
15
|
+
attr :default_text, true
|
16
|
+
def init
|
17
|
+
#--{{{
|
18
|
+
@config = DEFAULT_CONIFG
|
19
|
+
@search_path = DEFAULT_SEARCH_PATH
|
20
|
+
@basename = DEFAULT_BASENAME
|
21
|
+
#--}}}
|
22
|
+
end
|
23
|
+
def gen_template port = nil
|
24
|
+
#--{{{
|
25
|
+
port ||= STDOUT
|
26
|
+
buf = @default_text || @config.to_yaml
|
27
|
+
if port.respond_to? 'write'
|
28
|
+
port.write buf
|
29
|
+
port.write "\n"
|
30
|
+
else
|
31
|
+
open("#{ port }", 'w'){|f| f.puts buf}
|
32
|
+
end
|
33
|
+
#--}}}
|
34
|
+
end
|
35
|
+
def default= conf
|
36
|
+
#--{{{
|
37
|
+
if conf.respond_to?('read')
|
38
|
+
@default_text = munge conf.read
|
39
|
+
@config = YAML::load @default_text
|
40
|
+
else
|
41
|
+
case conf
|
42
|
+
when Hash
|
43
|
+
@config = conf
|
44
|
+
when Pathname
|
45
|
+
open(conf) do |f|
|
46
|
+
@default_text = munge f.read
|
47
|
+
@config = YAML::load @default_text
|
48
|
+
end
|
49
|
+
when String
|
50
|
+
@default_text = munge conf
|
51
|
+
@config = YAML::load @default_text
|
52
|
+
end
|
53
|
+
end
|
54
|
+
@config
|
55
|
+
#--}}}
|
56
|
+
end
|
57
|
+
alias set_default default=
|
58
|
+
def default(*a)
|
59
|
+
#--{{{
|
60
|
+
if a.empty?
|
61
|
+
@config ||= {}
|
62
|
+
else
|
63
|
+
self.default= a.first
|
64
|
+
end
|
65
|
+
#--}}}
|
66
|
+
end
|
67
|
+
def any(basename = @basename, *dirnames)
|
68
|
+
#--{{{
|
69
|
+
config = nil
|
70
|
+
dirnames = @search_path if dirnames.empty?
|
71
|
+
dirnames.each do |dirname|
|
72
|
+
path = File::join dirname, basename
|
73
|
+
path = File::expand_path path
|
74
|
+
if test ?e, path
|
75
|
+
config = self::new path
|
76
|
+
break
|
77
|
+
end
|
78
|
+
end
|
79
|
+
config || self::new('default')
|
80
|
+
#--}}}
|
81
|
+
end
|
82
|
+
def munge buf
|
83
|
+
#--{{{
|
84
|
+
buf.gsub(%r/\t/o,' ')
|
85
|
+
#--}}}
|
86
|
+
end
|
87
|
+
#--}}}
|
88
|
+
end
|
89
|
+
self.init
|
90
|
+
|
91
|
+
attr :path
|
92
|
+
def initialize path = 'default'
|
93
|
+
#--{{{
|
94
|
+
@path = nil
|
95
|
+
yaml = nil
|
96
|
+
if path.nil? or path and path =~ /^\s*default/io
|
97
|
+
yaml = self.class.default
|
98
|
+
@path = 'DEFAULT'
|
99
|
+
else path
|
100
|
+
yaml = YAML::load(self.class.munge(open(path).read))
|
101
|
+
@path = path
|
102
|
+
end
|
103
|
+
self.update yaml
|
104
|
+
#--}}}
|
105
|
+
end
|
106
|
+
def to_hash
|
107
|
+
#--{{{
|
108
|
+
{}.update self
|
109
|
+
#--}}}
|
110
|
+
end
|
111
|
+
#--}}}
|
112
|
+
end # class ConfigFile
|
113
|
+
ALib::Configfile = ALib::ConfigFile
|
@@ -0,0 +1,294 @@
|
|
1
|
+
# -*- Ruby -*-
|
2
|
+
# Copyright (C) 1998, 2001 Motoyuki Kasahara
|
3
|
+
#
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation; either version 2, or (at your option)
|
7
|
+
# any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
#
|
15
|
+
# Traverse a file tree, replacement of `find.rb'.
|
16
|
+
#
|
17
|
+
class ALib::Find2
|
18
|
+
#--{{{
|
19
|
+
#
|
20
|
+
# Constatnts
|
21
|
+
#
|
22
|
+
FIND1 = 1
|
23
|
+
FIND2 = 2
|
24
|
+
#
|
25
|
+
# Initializer.
|
26
|
+
#
|
27
|
+
def initialize(mode = FIND1)
|
28
|
+
#--{{{
|
29
|
+
@mode = mode
|
30
|
+
@depth = false
|
31
|
+
@follow = false
|
32
|
+
@xdev = false
|
33
|
+
|
34
|
+
@dirname_stats = Array.new
|
35
|
+
@found_files = Array.new
|
36
|
+
@target_device = 0
|
37
|
+
|
38
|
+
@handle = lambda { |file, stat_result, block|
|
39
|
+
case @mode
|
40
|
+
when FIND1
|
41
|
+
block ? block.call(file) : @found_files.push(file)
|
42
|
+
when FIND2
|
43
|
+
block ? block.call(file, stat_result) : @found_files.push([file, stat_result])
|
44
|
+
end
|
45
|
+
}
|
46
|
+
#--}}}
|
47
|
+
end
|
48
|
+
#
|
49
|
+
# Methods for accessing instances.
|
50
|
+
#
|
51
|
+
attr :depth
|
52
|
+
attr :follow
|
53
|
+
attr :xdev
|
54
|
+
#
|
55
|
+
# Find the directory `dirname'. (private)
|
56
|
+
#
|
57
|
+
def find(*arguments, &block)
|
58
|
+
#--{{{
|
59
|
+
#
|
60
|
+
# Parse options if specified.
|
61
|
+
#
|
62
|
+
#if arguments[0].type == Hash
|
63
|
+
#parse_options(arguments.shift)
|
64
|
+
#end
|
65
|
+
|
66
|
+
# hack
|
67
|
+
args = []
|
68
|
+
opts = []
|
69
|
+
arguments.each do |arg|
|
70
|
+
case arg
|
71
|
+
when Hash
|
72
|
+
opts << arg
|
73
|
+
else
|
74
|
+
args << arg
|
75
|
+
end
|
76
|
+
end
|
77
|
+
opts.each{|opt| parse_options opt}
|
78
|
+
files = args.flatten.compact
|
79
|
+
|
80
|
+
#
|
81
|
+
# If a block is not given to the `find' method, found files are
|
82
|
+
# recorded in this array.
|
83
|
+
#
|
84
|
+
@dirname_stats.clear
|
85
|
+
@found_files.clear
|
86
|
+
|
87
|
+
#
|
88
|
+
# Loop for each file in `files'.
|
89
|
+
#
|
90
|
+
files.each do |file|
|
91
|
+
catch(:prune) do
|
92
|
+
@dirname_stats.clear
|
93
|
+
|
94
|
+
#
|
95
|
+
# Get `stat' or `lstat' of `file'.
|
96
|
+
#
|
97
|
+
begin
|
98
|
+
if @follow
|
99
|
+
begin
|
100
|
+
stat_result = File.stat(file)
|
101
|
+
rescue Errno::ENOENT, Errno::EACCES
|
102
|
+
stat_result = File.lstat(file)
|
103
|
+
end
|
104
|
+
else
|
105
|
+
stat_result = File.lstat(file)
|
106
|
+
end
|
107
|
+
rescue Errno::ENOENT, Errno::EACCES
|
108
|
+
next
|
109
|
+
end
|
110
|
+
|
111
|
+
#
|
112
|
+
# Push `file' to the found stack, or yield with it,
|
113
|
+
# if the depth flag is enabled.
|
114
|
+
#
|
115
|
+
@handle[ file, stat_result, block ] if !@depth
|
116
|
+
|
117
|
+
#
|
118
|
+
# If `file' is a directory, find files recursively.
|
119
|
+
#
|
120
|
+
if stat_result.directory?
|
121
|
+
@xdev_device = stat_result.dev if @xdev
|
122
|
+
@dirname_stats.push(stat_result)
|
123
|
+
find_directory(file, block)
|
124
|
+
end
|
125
|
+
|
126
|
+
#
|
127
|
+
# Push `file' to the found stack, or yield with it.
|
128
|
+
# if the depth flag is disabled.
|
129
|
+
#
|
130
|
+
@handle[ file, stat_result, block ] if @depth
|
131
|
+
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
if block == nil
|
136
|
+
return @found_files
|
137
|
+
else
|
138
|
+
return nil
|
139
|
+
end
|
140
|
+
#--}}}
|
141
|
+
end
|
142
|
+
#
|
143
|
+
# Find the directory `dirname'. (private)
|
144
|
+
#
|
145
|
+
def find_directory(dirname, block)
|
146
|
+
#--{{{
|
147
|
+
#
|
148
|
+
# Open the directory `dirname'.
|
149
|
+
#
|
150
|
+
begin
|
151
|
+
dir = Dir.open(dirname)
|
152
|
+
rescue
|
153
|
+
return
|
154
|
+
end
|
155
|
+
|
156
|
+
#
|
157
|
+
# Read all directory entries except for `.' and `..'.
|
158
|
+
#
|
159
|
+
entries = Array.new
|
160
|
+
loop do
|
161
|
+
begin
|
162
|
+
entry = dir.read
|
163
|
+
rescue
|
164
|
+
break
|
165
|
+
end
|
166
|
+
break if entry == nil
|
167
|
+
next if entry == '.' || entry == '..'
|
168
|
+
entries.push(entry)
|
169
|
+
end
|
170
|
+
|
171
|
+
#
|
172
|
+
# Close `dir'.
|
173
|
+
#
|
174
|
+
dir.close
|
175
|
+
|
176
|
+
#
|
177
|
+
# Loop for each entry in this directory.
|
178
|
+
#
|
179
|
+
catch(:prune) do
|
180
|
+
entries.each do |entry|
|
181
|
+
#
|
182
|
+
# Set `entry_path' to the full path of `entry'.
|
183
|
+
#
|
184
|
+
if dirname[-1, 1] == File::Separator
|
185
|
+
entry_path = dirname + entry
|
186
|
+
else
|
187
|
+
entry_path = dirname + File::Separator + entry
|
188
|
+
end
|
189
|
+
|
190
|
+
#
|
191
|
+
# Get `stat' or `lstat' of `entry_path'.
|
192
|
+
#
|
193
|
+
begin
|
194
|
+
if @follow
|
195
|
+
begin
|
196
|
+
stat_result = File.stat(entry_path)
|
197
|
+
rescue Errno::ENOENT, Errno::EACCES
|
198
|
+
stat_result = File.lstat(entry_path)
|
199
|
+
end
|
200
|
+
else
|
201
|
+
stat_result = File.lstat(entry_path)
|
202
|
+
end
|
203
|
+
rescue Errno::ENOENT, Errno::EACCES
|
204
|
+
next
|
205
|
+
end
|
206
|
+
|
207
|
+
#
|
208
|
+
# Push `entry_path' to the found stack, or yield with it,
|
209
|
+
# if the depth flag is enabled.
|
210
|
+
#
|
211
|
+
|
212
|
+
@handle[ entry_path, stat_result, block ] if !@depth
|
213
|
+
|
214
|
+
#
|
215
|
+
# If `entry_path' is a directory, find recursively.
|
216
|
+
#
|
217
|
+
if stat_result.directory? \
|
218
|
+
&& (!@xdev || @xdev_device == stat_result.dev) \
|
219
|
+
&& (!@follow || !visited?(stat_result))
|
220
|
+
@dirname_stats.push(stat_result)
|
221
|
+
find_directory(entry_path, block)
|
222
|
+
@dirname_stats.pop
|
223
|
+
end
|
224
|
+
|
225
|
+
#
|
226
|
+
# Push `entry_path' to the found stack, or yield with it,
|
227
|
+
# if the depth flag is disabled.
|
228
|
+
#
|
229
|
+
@handle[ entry_path, stat_result, block ] if @depth
|
230
|
+
|
231
|
+
end
|
232
|
+
end
|
233
|
+
#--}}}
|
234
|
+
end
|
235
|
+
private :find_directory
|
236
|
+
#
|
237
|
+
# Find the directory `dirname'. (class method)
|
238
|
+
#
|
239
|
+
def self.find(*arguments, &block)
|
240
|
+
new.find(*arguments, &block)
|
241
|
+
end
|
242
|
+
#
|
243
|
+
# Find the directory `dirname'. (class method)
|
244
|
+
#
|
245
|
+
def self.find2(*arguments, &block)
|
246
|
+
new(FIND2).find(*arguments, &block)
|
247
|
+
end
|
248
|
+
#
|
249
|
+
# Parse options.
|
250
|
+
#
|
251
|
+
def parse_options(options)
|
252
|
+
#--{{{
|
253
|
+
return if options == nil
|
254
|
+
|
255
|
+
options.each_pair do |key, value|
|
256
|
+
case "#{ key }".strip.downcase
|
257
|
+
when 'depth'
|
258
|
+
@depth = value
|
259
|
+
when 'follow'
|
260
|
+
@follow = value
|
261
|
+
when 'xdev'
|
262
|
+
@xdev = value
|
263
|
+
else
|
264
|
+
raise ArgumentError, "unknown option - #{key}"
|
265
|
+
end
|
266
|
+
end
|
267
|
+
#--}}}
|
268
|
+
end
|
269
|
+
private :parse_options
|
270
|
+
#
|
271
|
+
# Prune the current visited directory.
|
272
|
+
#
|
273
|
+
def self.prune
|
274
|
+
#--{{{
|
275
|
+
throw :prune
|
276
|
+
#--}}}
|
277
|
+
end
|
278
|
+
#
|
279
|
+
# Did we visit the directory with the resouce `stat'? (private)
|
280
|
+
#
|
281
|
+
def visited?(stat_result)
|
282
|
+
#--{{{
|
283
|
+
dev = stat_result.dev
|
284
|
+
ino = stat_result.ino
|
285
|
+
@dirname_stats.each do |i|
|
286
|
+
return TRUE if i.dev == dev && i.ino == ino
|
287
|
+
end
|
288
|
+
return FALSE
|
289
|
+
#--}}}
|
290
|
+
end
|
291
|
+
private :visited?
|
292
|
+
#--}}}
|
293
|
+
end # class Find2
|
294
|
+
ALib::Find = ALib::Find2
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#
|
2
|
+
# file of lines, comments and blank lines are ignored
|
3
|
+
#
|
4
|
+
class ALib::ListFile < ::Array
|
5
|
+
#--{{{
|
6
|
+
class << self
|
7
|
+
#--{{{
|
8
|
+
def parse arg, &b
|
9
|
+
#--{{{
|
10
|
+
arg.respond_to?('gets') ? loadio(arg, &b) : open(arg.to_s){|f| loadio(f, &b)}
|
11
|
+
#--}}}
|
12
|
+
end
|
13
|
+
def loadio io
|
14
|
+
#--{{{
|
15
|
+
while((line = io.gets))
|
16
|
+
line.gsub!(%r/#.*/o,'')
|
17
|
+
next if line =~ %r/^[^\S]+$/o
|
18
|
+
line.gsub!(%r/^[^\S]+|[^\S]+$/o,'')
|
19
|
+
yield line
|
20
|
+
end
|
21
|
+
#--}}}
|
22
|
+
end
|
23
|
+
#--}}}
|
24
|
+
end
|
25
|
+
attr :path
|
26
|
+
def initialize arg
|
27
|
+
#--{{{
|
28
|
+
case arg
|
29
|
+
when Pathname, String
|
30
|
+
@path = path
|
31
|
+
self.class.parse(arg){|line| self << line}
|
32
|
+
when IO
|
33
|
+
@path = arg.respond_to?('path') ? arg.path : arg.to_s
|
34
|
+
self.class.loadio(arg){|line| self << line}
|
35
|
+
else
|
36
|
+
raise "cannot initialize from <#{ arg.inspect }>"
|
37
|
+
end
|
38
|
+
#--}}}
|
39
|
+
end
|
40
|
+
#--}}}
|
41
|
+
end # class ListFile
|
42
|
+
ALib::Listfile = ALib::ListFile
|