alib 0.3.1 → 0.4.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/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
|