vcs 0.1 → 0.2.148
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/Rakefile +17 -3
- data/bin/vcs +57 -34
- data/doc/jamis.rb +564 -0
- data/ruby_ex/abstract.rb +254 -0
- data/ruby_ex/abstract_node.rb +85 -0
- data/ruby_ex/algorithms/simulated_annealing.rb +140 -0
- data/ruby_ex/array_each_pair.rb +18 -0
- data/ruby_ex/ask.rb +101 -0
- data/ruby_ex/attributed_class.rb +302 -0
- data/ruby_ex/cache.rb +373 -0
- data/ruby_ex/checkout.rb +12 -0
- data/ruby_ex/choose.rb +271 -0
- data/ruby_ex/commands.rb +18 -0
- data/ruby_ex/commands/command.rb +401 -0
- data/ruby_ex/commands/datas.rb +16 -0
- data/ruby_ex/commands/datas/data.rb +33 -0
- data/ruby_ex/commands/datas/factory.rb +66 -0
- data/ruby_ex/commands/factory.rb +66 -0
- data/ruby_ex/commands/helpers.rb +67 -0
- data/ruby_ex/commands/pipe.rb +64 -0
- data/ruby_ex/commands/runners.rb +17 -0
- data/ruby_ex/commands/runners/exec.rb +49 -0
- data/ruby_ex/commands/runners/fork.rb +97 -0
- data/ruby_ex/commands/runners/runner.rb +107 -0
- data/ruby_ex/commands/seq.rb +27 -0
- data/ruby_ex/config_file.rb +96 -0
- data/ruby_ex/const_regexp.rb +59 -0
- data/ruby_ex/daemon.rb +134 -0
- data/ruby_ex/diff.rb +667 -0
- data/ruby_ex/dlogger.rb +62 -0
- data/ruby_ex/drb/dispatcher.rb +252 -0
- data/ruby_ex/drb/dispatcher_server_test.rb +29 -0
- data/ruby_ex/drb/drb_observable.rb +97 -0
- data/ruby_ex/drb/drb_observable_pool.rb +27 -0
- data/ruby_ex/drb/drb_service.rb +43 -0
- data/ruby_ex/drb/drb_undumped_attributes.rb +55 -0
- data/ruby_ex/drb/drb_undumped_indexed_object.rb +54 -0
- data/ruby_ex/drb/insecure_protected_methods.rb +103 -0
- data/ruby_ex/drb/session_client_test.rb +40 -0
- data/ruby_ex/drb/session_manager.rb +246 -0
- data/ruby_ex/drb/session_server.rb +53 -0
- data/ruby_ex/dtime.rb +143 -0
- data/ruby_ex/dumpable_proc.rb +63 -0
- data/ruby_ex/exception.rb +32 -0
- data/ruby_ex/filetype.rb +229 -0
- data/ruby_ex/fileutils_ex.rb +44 -0
- data/ruby_ex/fold.rb +58 -0
- data/ruby_ex/generate_id.rb +44 -0
- data/ruby_ex/hookable.rb +262 -0
- data/ruby_ex/hooker.rb +54 -0
- data/ruby_ex/inactive_timeout.rb +137 -0
- data/ruby_ex/indexed_node.rb +66 -0
- data/ruby_ex/io_marshal.rb +100 -0
- data/ruby_ex/ioo.rb +194 -0
- data/ruby_ex/labeled_node.rb +63 -0
- data/ruby_ex/logger_observer.rb +23 -0
- data/ruby_ex/md5sum.rb +66 -0
- data/ruby_ex/mktemp.rb +208 -0
- data/ruby_ex/module/attr_once.rb +36 -0
- data/ruby_ex/module/autoload_tree.rb +75 -0
- data/ruby_ex/module/hierarchy.rb +335 -0
- data/ruby_ex/module/instance_method_visibility.rb +73 -0
- data/ruby_ex/module_ex.rb +11 -0
- data/ruby_ex/node.rb +80 -0
- data/ruby_ex/object_monitor.rb +145 -0
- data/ruby_ex/object_monitor_activity.rb +33 -0
- data/ruby_ex/observable.rb +140 -0
- data/ruby_ex/observable_pool.rb +293 -0
- data/ruby_ex/orderedhash.rb +252 -0
- data/ruby_ex/pathname_ex.rb +152 -0
- data/ruby_ex/pp_hierarchy.rb +29 -0
- data/ruby_ex/pseudo_cache.rb +190 -0
- data/ruby_ex/queue.rb +56 -0
- data/ruby_ex/random_generators.rb +25 -0
- data/ruby_ex/random_generators/random_generator.rb +31 -0
- data/ruby_ex/random_generators/ruby.rb +23 -0
- data/ruby_ex/safe_eval.rb +348 -0
- data/ruby_ex/sendmail.rb +215 -0
- data/ruby_ex/service_manager.rb +121 -0
- data/ruby_ex/session/administrable.rb +120 -0
- data/ruby_ex/session/client.rb +153 -0
- data/ruby_ex/session/const.rb +18 -0
- data/ruby_ex/session/dispatcher.rb +184 -0
- data/ruby_ex/session/error.rb +21 -0
- data/ruby_ex/session/fetchable.rb +57 -0
- data/ruby_ex/session/fetcher.rb +62 -0
- data/ruby_ex/session/hookable.rb +26 -0
- data/ruby_ex/session/profile.rb +110 -0
- data/ruby_ex/session/server.rb +582 -0
- data/ruby_ex/session/test/administrable_test.rb +337 -0
- data/ruby_ex/session/test/basic_test.rb +523 -0
- data/ruby_ex/session/test/dispatcher_test.rb +409 -0
- data/ruby_ex/session/test/fetchable_test.rb +119 -0
- data/ruby_ex/session/test/sub_server_test.rb +188 -0
- data/ruby_ex/shuffle.rb +30 -0
- data/ruby_ex/spring.rb +136 -0
- data/ruby_ex/spring_set.rb +137 -0
- data/ruby_ex/string_ex.rb +28 -0
- data/ruby_ex/symtbl.rb +106 -0
- data/ruby_ex/synflow.rb +474 -0
- data/ruby_ex/test/unit/ui/yaml/testrunner.rb +164 -0
- data/ruby_ex/thread_mutex.rb +10 -0
- data/ruby_ex/timeout_ex.rb +81 -0
- data/ruby_ex/top_down.rb +73 -0
- data/ruby_ex/trace.rb +26 -0
- data/ruby_ex/uri/druby.rb +81 -0
- data/ruby_ex/uri/file.rb +65 -0
- data/ruby_ex/uri/ftp_ex.rb +37 -0
- data/ruby_ex/uri/http_ex.rb +43 -0
- data/ruby_ex/uri/ssh.rb +92 -0
- data/ruby_ex/uri/svn.rb +118 -0
- data/ruby_ex/uri_ex.rb +45 -0
- data/ruby_ex/verbose_object.rb +30 -0
- data/ruby_ex/version.rb +66 -0
- data/ruby_ex/yaml/basenode_ext.rb +63 -0
- data/ruby_ex/yaml/chop_header.rb +23 -0
- data/ruby_ex/yaml/transform.rb +449 -0
- data/ruby_ex/yaml/yregexpath.rb +76 -0
- data/src/changelog.rb +28 -18
- data/src/conflict.rb +20 -0
- data/src/diff.rb +18 -0
- data/src/diffstat.rb +9 -3
- data/src/last_changed_date.rb +18 -0
- data/src/mail.rb +33 -65
- data/src/message.rb +15 -9
- data/src/mycommit.rb +29 -14
- data/src/news.rb +24 -3
- data/src/status.rb +17 -0
- data/src/svn.rb +2 -2
- data/src/vcs.rb +24 -3
- metadata +124 -5
- data/lrdetools.rb +0 -12
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# AUTHOR
|
|
2
|
+
# jan molic /mig/at/1984/dot/cz/
|
|
3
|
+
# updated by: Nicolas Pouillard <ertai@lrde.epita.fr>
|
|
4
|
+
#
|
|
5
|
+
# DESCRIPTION
|
|
6
|
+
# Override hash to make it creation order preserved.
|
|
7
|
+
# This will be obsolete - it is better to use special OrderedHash class
|
|
8
|
+
# than overriding.
|
|
9
|
+
# Public domain.
|
|
10
|
+
#
|
|
11
|
+
# THANKS
|
|
12
|
+
# Andrew Johnson for his suggestions and fixes of Hash[],
|
|
13
|
+
# merge, to_a, inspect and shift
|
|
14
|
+
#
|
|
15
|
+
# USAGE
|
|
16
|
+
# just require this file, examples are at the end
|
|
17
|
+
# you can try to run this file (ruby orderedhash.rb)
|
|
18
|
+
#
|
|
19
|
+
|
|
20
|
+
# $LastChangedBy: ertai $
|
|
21
|
+
# $Id: orderedhash.rb 152 2005-02-13 09:31:49Z ertai $
|
|
22
|
+
|
|
23
|
+
module OrderedHash_ext
|
|
24
|
+
|
|
25
|
+
def store ( a, b )
|
|
26
|
+
@order.push a unless has_key? a
|
|
27
|
+
super a,b
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def []= ( a, b )
|
|
31
|
+
@order.push a unless has_key? a
|
|
32
|
+
super a,b
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def == ( hsh2 )
|
|
36
|
+
return false if !hsh2.respond_to? :order or @order != hsh2.order
|
|
37
|
+
super hsh2
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def clear
|
|
41
|
+
@order = []
|
|
42
|
+
super
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def delete ( key )
|
|
46
|
+
@order.delete key
|
|
47
|
+
super
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def each_key
|
|
51
|
+
@order.each { |k| yield k }
|
|
52
|
+
self
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def each_value
|
|
56
|
+
@order.each { |k| yield self[k] }
|
|
57
|
+
self
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def each
|
|
61
|
+
@order.each { |k| yield(k, self[k]) }
|
|
62
|
+
self
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
alias :each_pair :each
|
|
66
|
+
|
|
67
|
+
def delete_if
|
|
68
|
+
@order.clone.each do |k|
|
|
69
|
+
delete k if yield(k, self[k])
|
|
70
|
+
end
|
|
71
|
+
self
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def values
|
|
75
|
+
ary = []
|
|
76
|
+
@order.each { |k| ary << self[k] }
|
|
77
|
+
ary
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def keys
|
|
81
|
+
@order
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def invert
|
|
85
|
+
hsh2 = self.class.new
|
|
86
|
+
@order.each { |k| hsh2[self[k]] = k }
|
|
87
|
+
hsh2
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def reject ( &block )
|
|
91
|
+
self.dup.delete_if(&block)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def reject! ( &block )
|
|
95
|
+
hsh2 = reject(&block)
|
|
96
|
+
self == hsh2 ? nil : hsh2
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def replace ( hsh2 )
|
|
100
|
+
@order = hsh2.keys
|
|
101
|
+
super hsh2
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def shift
|
|
105
|
+
key = @order.first
|
|
106
|
+
key ? [key,delete(key)] : super
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def to_a
|
|
110
|
+
ary = []
|
|
111
|
+
each { |k,v| ary << [k,v] }
|
|
112
|
+
ary
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def to_s
|
|
116
|
+
to_a.to_s
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def update ( hsh2 )
|
|
120
|
+
hsh2.each { |k,v| self[k] = v }
|
|
121
|
+
self
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def merge! ( hsh2 )
|
|
125
|
+
hsh2.each { |k,v| self[k] = v }
|
|
126
|
+
self
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def merge ( hsh2 )
|
|
130
|
+
self.dup.update(hsh2)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def select
|
|
134
|
+
ary = []
|
|
135
|
+
each { |k,v| ary << [k,v] if yield k,v }
|
|
136
|
+
ary
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def ordered?
|
|
140
|
+
!@order.nil?
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
end # module OrderedHash_ext
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class OHash < Hash
|
|
147
|
+
|
|
148
|
+
attr_accessor :order
|
|
149
|
+
|
|
150
|
+
alias :unordered_keys :keys
|
|
151
|
+
|
|
152
|
+
include OrderedHash_ext
|
|
153
|
+
|
|
154
|
+
def initialize ( *a )
|
|
155
|
+
@order = unordered_keys
|
|
156
|
+
super
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def self.[] ( *args )
|
|
160
|
+
hsh = OHash.new
|
|
161
|
+
if Hash === args[0]
|
|
162
|
+
hsh.replace args[0]
|
|
163
|
+
elsif (args.size % 2) != 0
|
|
164
|
+
raise ArgumentError, "odd number of elements for Hash"
|
|
165
|
+
else
|
|
166
|
+
hsh[args.shift] = args.shift while args.size > 0
|
|
167
|
+
end
|
|
168
|
+
hsh
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
end # class OHash
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class Hash
|
|
175
|
+
|
|
176
|
+
def ordered?
|
|
177
|
+
false
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
end # class Hash
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
if defined? TEST_MODE or __FILE__ == $0
|
|
184
|
+
|
|
185
|
+
require 'test/unit'
|
|
186
|
+
class OrderedHashTest < Test::Unit::TestCase
|
|
187
|
+
|
|
188
|
+
def check_ordered ( h, ref )
|
|
189
|
+
h.store(4,3)
|
|
190
|
+
h.store(2,3)
|
|
191
|
+
assert_equal(h.to_a, ref)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def test_ordered
|
|
195
|
+
check_ordered(OHash.new, [[4, 3], [2, 3]])
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def test_unorderd
|
|
199
|
+
check_ordered(Hash.new, [[2, 3], [4, 3]])
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def test_simply
|
|
203
|
+
# You can do simply
|
|
204
|
+
hsh = OHash.new
|
|
205
|
+
hsh['z'] = 1
|
|
206
|
+
hsh['a'] = 2
|
|
207
|
+
hsh['c'] = 3
|
|
208
|
+
assert_equal(hsh.keys, ['z','a','c'])
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def test_preserve
|
|
212
|
+
# or using OrderedHash[] method
|
|
213
|
+
hsh = OHash['z', 1, 'a', 2, 'c', 3]
|
|
214
|
+
hsh2 = OHash['a', 2, 'z', 1, 'c', 3]
|
|
215
|
+
assert_equal(hsh.keys, ['z','a','c'])
|
|
216
|
+
assert_not_equal(hsh, hsh2)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def test_dont_preserve
|
|
220
|
+
# but this don't preserve order
|
|
221
|
+
hsh = OHash['z'=>1, 'a'=>2, 'c'=>3]
|
|
222
|
+
hsh2 = OHash['a'=>2, 'z'=>1, 'c'=>3]
|
|
223
|
+
assert_equal(hsh, hsh2)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def test_unorderd_empty
|
|
227
|
+
check_ordered({}, [[2, 3], [4, 3]])
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def test_little_ordered
|
|
231
|
+
a = (0..11).to_a
|
|
232
|
+
h = OHash[*a]
|
|
233
|
+
assert_equal(h.to_s, a.to_s)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def test_big_ordered
|
|
237
|
+
a = (0..501).to_a
|
|
238
|
+
h = OHash[*a]
|
|
239
|
+
assert_equal(h.to_s, a.to_s)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def test_eql
|
|
243
|
+
assert_nothing_raised { OHash.new == {} }
|
|
244
|
+
assert_not_equal OHash.new, {}
|
|
245
|
+
assert_equal OHash.new, OHash.new
|
|
246
|
+
assert_equal OHash[1,2,3,4], OHash[1,2,3,4]
|
|
247
|
+
assert_not_equal OHash[1,2,3,4], OHash[3,4,1,2]
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
end # OrderedHashTest
|
|
251
|
+
|
|
252
|
+
end
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
|
|
2
|
+
# Author: Nicolas Despres <polrop@lrde.epita.fr>.
|
|
3
|
+
# License: Gnu General Public License.
|
|
4
|
+
|
|
5
|
+
# $LastChangedBy: ertai $
|
|
6
|
+
# $Id: pathname_ex.rb 215 2005-05-08 10:58:49Z ertai $
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
require 'pathname'
|
|
10
|
+
require 'fileutils_ex'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Pathname
|
|
14
|
+
|
|
15
|
+
def ensure_mkdir
|
|
16
|
+
(mkdir) rescue Errno::EEXIST
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def ensure_mkpath
|
|
20
|
+
(mkpath) rescue Errno::EEXIST
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def extsplit ( aChar='.' )
|
|
24
|
+
raise ArgumentError, "#{aChar} is not just a char" if aChar.size != 1
|
|
25
|
+
aChar = Regexp.escape(aChar)
|
|
26
|
+
to_s =~ /^(.*?)(#{aChar}[^#{aChar}]*)?$/
|
|
27
|
+
[Pathname.new($1), $2 || '']
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def cp ( aPath )
|
|
31
|
+
FileUtils.cp self.to_s, aPath.to_s
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def cp_r ( aPath )
|
|
35
|
+
FileUtils.cp_r self.to_s, aPath.to_s
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def cp_rf ( aPath )
|
|
39
|
+
FileUtils.cp_rf self.to_s, aPath.to_s
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def rm
|
|
43
|
+
FileUtils.rm self.to_s
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def rm_r
|
|
47
|
+
FileUtils.rm_r self.to_s
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def rm_rf
|
|
51
|
+
FileUtils.rm_rf self.to_s
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def rm_f
|
|
55
|
+
FileUtils.rm_f self.to_s
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Allow this kind of things:
|
|
59
|
+
#
|
|
60
|
+
# root = Pathname.new('/tmp/test')
|
|
61
|
+
# foo, bar = 'foo', 'bar'
|
|
62
|
+
#
|
|
63
|
+
# ...
|
|
64
|
+
#
|
|
65
|
+
# (root/foo/bar).each_line do |line|
|
|
66
|
+
# ...
|
|
67
|
+
# end
|
|
68
|
+
alias :/ :+
|
|
69
|
+
|
|
70
|
+
def to_io
|
|
71
|
+
@open_mode ||= 'r'
|
|
72
|
+
open(@open_mode)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
attr_accessor :open_mode
|
|
76
|
+
|
|
77
|
+
module ShortCut
|
|
78
|
+
|
|
79
|
+
# Allow to use this sort of constructions:
|
|
80
|
+
#
|
|
81
|
+
# `/path/to/a/file`.open do |f|
|
|
82
|
+
# ...
|
|
83
|
+
# end
|
|
84
|
+
def ` ( path )
|
|
85
|
+
Pathname.new(path)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end # class Pathname
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class String
|
|
94
|
+
|
|
95
|
+
def to_path
|
|
96
|
+
Pathname.new(self)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end # class String
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
#
|
|
104
|
+
# Unit test suite
|
|
105
|
+
#
|
|
106
|
+
if defined? TEST_MODE or $0 == __FILE__
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
require 'test/unit'
|
|
110
|
+
require 'tempfile'
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class PathnameExTest < Test::Unit::TestCase
|
|
114
|
+
|
|
115
|
+
#
|
|
116
|
+
# Tests
|
|
117
|
+
#
|
|
118
|
+
def test_ensure_dir
|
|
119
|
+
p = nil
|
|
120
|
+
begin
|
|
121
|
+
name = Tempfile.new('pathname')
|
|
122
|
+
p = Pathname.new(name.path)
|
|
123
|
+
name.delete
|
|
124
|
+
assert(! p.directory?, 'no directory')
|
|
125
|
+
assert_nothing_raised { p.ensure_mkdir }
|
|
126
|
+
assert(p.directory?, 'directory')
|
|
127
|
+
assert_nothing_raised { p.ensure_mkdir }
|
|
128
|
+
assert(p.directory?, 'still directory')
|
|
129
|
+
ensure
|
|
130
|
+
p.rmdir unless p.nil?
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
include Pathname::ShortCut
|
|
135
|
+
|
|
136
|
+
def test_simple
|
|
137
|
+
assert_equal([`path.ext1`, '.ext2'], `path.ext1.ext2`.extsplit)
|
|
138
|
+
assert_equal([`path`, ''], `path`.extsplit)
|
|
139
|
+
assert_equal([`path`, '.'], `path.`.extsplit)
|
|
140
|
+
assert_equal([`path`, '-ext'], `path-ext`.extsplit('-'))
|
|
141
|
+
assert_equal([`path-ext1`, '-ext2'], `path-ext1-ext2`.extsplit('-'))
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def test_slash
|
|
145
|
+
assert_equal(`path/to/a/file`, `path`/'to'/'a'/'file')
|
|
146
|
+
path, to, a, file = `/path`, 'to', 'a', 'file'
|
|
147
|
+
assert_equal(`/path/to/a/file`, path/to/a/file)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
end # class PathnameExTest
|
|
151
|
+
|
|
152
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
|
|
2
|
+
# Author: Nicolas Despres <polrop@lrde.epita.fr>.
|
|
3
|
+
# License: Gnu General Public License.
|
|
4
|
+
|
|
5
|
+
# $LastChangedBy: polrop $
|
|
6
|
+
# $Id: hierarchy.rb 145 2005-01-30 14:16:14Z polrop $
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Hash
|
|
10
|
+
|
|
11
|
+
# Pretty print a hash symbolizing a class hierarchy.
|
|
12
|
+
def pp_hierarchy(prefix=//, abstract=false)
|
|
13
|
+
pp_hierarchy_rec('', prefix, abstract)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
protected
|
|
17
|
+
def pp_hierarchy_rec(indent, prefix, abstract)
|
|
18
|
+
self.each do |k, v|
|
|
19
|
+
k_str = k.to_s.sub(prefix, '')
|
|
20
|
+
if abstract and k.abstract?
|
|
21
|
+
puts "#{indent}/#{k_str}/"
|
|
22
|
+
else
|
|
23
|
+
puts "#{indent}#{k_str}"
|
|
24
|
+
end
|
|
25
|
+
v.pp_hierarchy_rec(indent + ' ', prefix, abstract)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end # class Hash
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
|
|
2
|
+
# Author: Nicolas Despres <polrop@lrde.epita.fr>.
|
|
3
|
+
# License: Gnu General Public License.
|
|
4
|
+
|
|
5
|
+
# $LastChangedBy: ertai $
|
|
6
|
+
# $Id: pseudo_cache.rb 186 2005-04-03 00:07:45Z ertai $
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
require 'pathname'
|
|
10
|
+
require 'md5'
|
|
11
|
+
|
|
12
|
+
require 'md5sum'
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class PseudoCache
|
|
16
|
+
|
|
17
|
+
#
|
|
18
|
+
# Constants
|
|
19
|
+
#
|
|
20
|
+
DEFAULT_CACHE_REPOSITORY = '/var/cache/ruby_ex_cache'
|
|
21
|
+
|
|
22
|
+
#
|
|
23
|
+
# Constructor
|
|
24
|
+
#
|
|
25
|
+
def initialize(repository=DEFAULT_CACHE_REPOSITORY)
|
|
26
|
+
@repository = check_repository(repository)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#
|
|
30
|
+
# Methods
|
|
31
|
+
#
|
|
32
|
+
def get_key(name)
|
|
33
|
+
Pathname.new(Digest::MD5.new(name).to_s)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def get_full_key(name)
|
|
37
|
+
@repository + Digest::MD5.new(name).to_s
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
alias [] get_full_key
|
|
41
|
+
|
|
42
|
+
def get_name(name)
|
|
43
|
+
name = get_full_key(name) + 'name'
|
|
44
|
+
name.open('r') { |f| return f.gets.chomp }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def get_md5sum(name)
|
|
48
|
+
md5 = get_full_key(name) + 'md5sum'
|
|
49
|
+
md5.open('r') { |f| return f.gets.chomp }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def present?(name)
|
|
53
|
+
get_full_key(name).directory?
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def up_to_date?(name, md5sum)
|
|
57
|
+
(get_md5sum(name) == md5sum.to_s)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def add(name, &block)
|
|
61
|
+
key = get_full_key(name)
|
|
62
|
+
unless key.exist?
|
|
63
|
+
key.mkdir
|
|
64
|
+
(key + 'name').open('w') { |f| f.puts(name) }
|
|
65
|
+
data = key + 'data'
|
|
66
|
+
data.open('w', &block)
|
|
67
|
+
(key + 'md5sum').open('w') { |f| f.puts(File.md5sum(data).to_s) }
|
|
68
|
+
end
|
|
69
|
+
key
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def read(name, &block)
|
|
73
|
+
key = get_full_key(name)
|
|
74
|
+
(key + 'data').open(&block)
|
|
75
|
+
key
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def del(name)
|
|
79
|
+
key = get_full_key(name)
|
|
80
|
+
key.rmtree if key.exist?
|
|
81
|
+
key
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def replace(name, new_name, &block)
|
|
85
|
+
add(new_name, &block)
|
|
86
|
+
del(name)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def each(&block)
|
|
90
|
+
@repository.each_entry do |p|
|
|
91
|
+
next if p.to_s =~ /^\./
|
|
92
|
+
(@repository + p + 'name').open('r') { |f| block[f.gets.chomp] }
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def clear
|
|
97
|
+
@repository.rmtree
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def create
|
|
101
|
+
@repository.mkdir
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def recreate
|
|
105
|
+
clear
|
|
106
|
+
create
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
protected
|
|
110
|
+
def check_repository(repository)
|
|
111
|
+
repo = Pathname.new(repository)
|
|
112
|
+
unless (repo.directory? and
|
|
113
|
+
repo.writable? and
|
|
114
|
+
repo.readable? and
|
|
115
|
+
repo.executable?)
|
|
116
|
+
raise(ArgumentError, "`#{repository}' - bad repository")
|
|
117
|
+
end
|
|
118
|
+
repo
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
end # class PseudoCache
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
#
|
|
125
|
+
# Unit test suite
|
|
126
|
+
#
|
|
127
|
+
if defined? TEST_MODE or __FILE__ == $0
|
|
128
|
+
|
|
129
|
+
require 'test/unit/ui/yaml/testrunner'
|
|
130
|
+
require 'mktemp'
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class PseudoCacheTest < Test::Unit::TestCase
|
|
134
|
+
|
|
135
|
+
#
|
|
136
|
+
# Tests
|
|
137
|
+
#
|
|
138
|
+
def test_simple
|
|
139
|
+
Tempfile.mktemp('cache') do |repo|
|
|
140
|
+
assert_raises(ArgumentError) { PseudoCache.new(repo) }
|
|
141
|
+
repo.mkdir
|
|
142
|
+
cache = nil
|
|
143
|
+
assert_nothing_raised { cache = PseudoCache.new(repo) }
|
|
144
|
+
assert_not_nil(cache)
|
|
145
|
+
assert(! cache.present?('toto'))
|
|
146
|
+
assert_raises(Errno::ENOENT) { cache.get_name('toto') }
|
|
147
|
+
assert_raises(Errno::ENOENT) { cache.get_md5sum('toto') }
|
|
148
|
+
assert_equal(cache['toto'],
|
|
149
|
+
cache.add('toto') { |f| f.puts('toto'); f.puts('tata') })
|
|
150
|
+
assert(cache.present?('toto'))
|
|
151
|
+
assert_equal('toto', cache.get_name('toto'))
|
|
152
|
+
cache.read('toto') do |f|
|
|
153
|
+
assert_equal("toto\n", f.gets)
|
|
154
|
+
assert_equal("tata\n", f.gets)
|
|
155
|
+
assert(f.eof?)
|
|
156
|
+
end
|
|
157
|
+
assert(! cache.present?('tata'))
|
|
158
|
+
assert(cache.present?('toto'))
|
|
159
|
+
cache.replace('toto', 'tata') { |f| f.puts('foo'); f.puts('bar') }
|
|
160
|
+
assert(! cache.present?('toto'))
|
|
161
|
+
assert(cache.present?('tata'))
|
|
162
|
+
cache.read('tata') do |f|
|
|
163
|
+
assert_equal("foo\n", f.gets)
|
|
164
|
+
assert_equal("bar\n", f.gets)
|
|
165
|
+
assert(f.eof?)
|
|
166
|
+
end
|
|
167
|
+
assert_equal(cache.get_full_key('toto'),
|
|
168
|
+
cache.add('toto') { |f| f.puts('toto'); f.puts('tata') })
|
|
169
|
+
assert(cache.up_to_date?('toto', cache.get_md5sum('toto')))
|
|
170
|
+
names = []
|
|
171
|
+
cache.each { |p| names << p }
|
|
172
|
+
assert_equal(2, names.size)
|
|
173
|
+
names.sort!
|
|
174
|
+
assert_equal('tata', names[0].to_s)
|
|
175
|
+
assert_equal('toto', names[1].to_s)
|
|
176
|
+
cache.del('toto')
|
|
177
|
+
assert(! cache.present?('toto'))
|
|
178
|
+
assert(cache.present?('tata'))
|
|
179
|
+
cache.clear
|
|
180
|
+
assert(! cache.present?('tata'))
|
|
181
|
+
cache.create
|
|
182
|
+
assert(! cache.present?('tata'))
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
end # class PseudoCacheTest
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
end
|
|
190
|
+
|