ruby_ex 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/AUTHORS +51 -0
  2. data/ChangeLog +1763 -0
  3. data/NEWS +3 -0
  4. data/README +1 -0
  5. data/Rakefile +8 -0
  6. data/SPEC.dyn.yml +10 -0
  7. data/SPEC.gem.yml +269 -0
  8. data/SPEC.yml +36 -0
  9. data/src/abstract.rb +253 -0
  10. data/src/abstract_node.rb +85 -0
  11. data/src/algorithms.rb +12 -0
  12. data/src/algorithms/simulated_annealing.rb +142 -0
  13. data/src/ask.rb +100 -0
  14. data/src/attributed_class.rb +303 -0
  15. data/src/cache.rb +350 -0
  16. data/src/checkout.rb +12 -0
  17. data/src/choose.rb +271 -0
  18. data/src/commands.rb +20 -0
  19. data/src/commands/command.rb +492 -0
  20. data/src/commands/datas.rb +16 -0
  21. data/src/commands/datas/composite.rb +31 -0
  22. data/src/commands/datas/data.rb +65 -0
  23. data/src/commands/datas/factory.rb +69 -0
  24. data/src/commands/datas/temp.rb +26 -0
  25. data/src/commands/factory.rb +67 -0
  26. data/src/commands/helpers.rb +81 -0
  27. data/src/commands/pipe.rb +66 -0
  28. data/src/commands/runners.rb +16 -0
  29. data/src/commands/runners/exec.rb +50 -0
  30. data/src/commands/runners/fork.rb +130 -0
  31. data/src/commands/runners/runner.rb +140 -0
  32. data/src/commands/runners/system.rb +57 -0
  33. data/src/commands/seq.rb +32 -0
  34. data/src/config_file.rb +95 -0
  35. data/src/const_regexp.rb +57 -0
  36. data/src/daemon.rb +135 -0
  37. data/src/diff.rb +665 -0
  38. data/src/dlogger.rb +62 -0
  39. data/src/drb/drb_observable.rb +95 -0
  40. data/src/drb/drb_observable_pool.rb +27 -0
  41. data/src/drb/drb_service.rb +44 -0
  42. data/src/drb/drb_undumped_attributes.rb +56 -0
  43. data/src/drb/drb_undumped_indexed_object.rb +55 -0
  44. data/src/drb/insecure_protected_methods.rb +101 -0
  45. data/src/drb_ex.rb +12 -0
  46. data/src/dumpable_proc.rb +57 -0
  47. data/src/filetype.rb +229 -0
  48. data/src/generate_id.rb +44 -0
  49. data/src/histogram.rb +222 -0
  50. data/src/hookable.rb +283 -0
  51. data/src/hooker.rb +54 -0
  52. data/src/indexed_node.rb +65 -0
  53. data/src/io_marshal.rb +99 -0
  54. data/src/ioo.rb +193 -0
  55. data/src/labeled_node.rb +62 -0
  56. data/src/logger_observer.rb +24 -0
  57. data/src/md5sum.rb +70 -0
  58. data/src/module/autoload_tree.rb +65 -0
  59. data/src/module/hierarchy.rb +334 -0
  60. data/src/module/instance_method_visibility.rb +71 -0
  61. data/src/node.rb +81 -0
  62. data/src/object_monitor.rb +143 -0
  63. data/src/object_monitor_activity.rb +34 -0
  64. data/src/observable.rb +138 -0
  65. data/src/observable_pool.rb +291 -0
  66. data/src/orderedhash.rb +252 -0
  67. data/src/pp_hierarchy.rb +30 -0
  68. data/src/random_generators.rb +29 -0
  69. data/src/random_generators/random_generator.rb +33 -0
  70. data/src/random_generators/ruby.rb +25 -0
  71. data/src/ruby_ex.rb +124 -0
  72. data/src/safe_eval.rb +346 -0
  73. data/src/sendmail.rb +214 -0
  74. data/src/service_manager.rb +122 -0
  75. data/src/shuffle.rb +30 -0
  76. data/src/spring.rb +134 -0
  77. data/src/spring_set.rb +134 -0
  78. data/src/symtbl.rb +108 -0
  79. data/src/synflow.rb +474 -0
  80. data/src/thread_mutex.rb +11 -0
  81. data/src/timeout_ex.rb +79 -0
  82. data/src/trace.rb +26 -0
  83. data/src/uri/druby.rb +78 -0
  84. data/src/uri/file.rb +63 -0
  85. data/src/uri/ftp_ex.rb +36 -0
  86. data/src/uri/http_ex.rb +41 -0
  87. data/src/uri/pgsql.rb +136 -0
  88. data/src/uri/ssh.rb +87 -0
  89. data/src/uri/svn.rb +113 -0
  90. data/src/uri_ex.rb +71 -0
  91. data/src/verbose_object.rb +70 -0
  92. data/src/yaml/basenode_ext.rb +63 -0
  93. data/src/yaml/chop_header.rb +24 -0
  94. data/src/yaml/transform.rb +450 -0
  95. data/src/yaml/yregexpath.rb +76 -0
  96. data/test/algorithms/simulated_annealing_test.rb +102 -0
  97. data/test/check-pkg-ruby_ex.yml +15 -0
  98. data/test/check-ruby_ex.yml +12 -0
  99. data/test/resources/autoload_tree/A.rb +11 -0
  100. data/test/resources/autoload_tree/B.rb +10 -0
  101. data/test/resources/autoload_tree/foo/C.rb +18 -0
  102. data/test/resources/foo.txt +6 -0
  103. data/test/sanity-suite.yml +12 -0
  104. data/test/sanity/multiple-requires.yml +20 -0
  105. data/test/sanity/single-requires.yml +24 -0
  106. data/test/test-unit-setup.rb +6 -0
  107. data/test/unit-suite.yml +14 -0
  108. metadata +269 -0
data/src/sendmail.rb ADDED
@@ -0,0 +1,214 @@
1
+ #!/usr/bin/env ruby
2
+ # Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
3
+ # Copyright:: Copyright (c) 2004, 2005 Nicolas Pouillard. All rights reserved.
4
+ # License:: GNU General Public License (GPL).
5
+ # Revision:: $Id: header 98 2004-09-29 12:07:43Z ertai $
6
+
7
+ require 'pathname'
8
+ require 'ostruct'
9
+ require 'optparse'
10
+
11
+
12
+ class Sendmail
13
+
14
+ MAIL_FILE = Pathname.new(',mail')
15
+
16
+ def initialize
17
+ require 'ruby_ex'
18
+ require 'yaml/chop_header'
19
+ end
20
+
21
+ def parse_mail_options ( *args )
22
+ email = (defined? EMAIL)? EMAIL : ENV['EMAIL']
23
+ full_name = (defined? FULLNAME)? FULLNAME : ENV['FULLNAME']
24
+ full_email = (defined? FULL_EMAIL)? FULL_EMAIL : "#{full_name} <#{email}>"
25
+ options = OpenStruct.new(
26
+ :from_name => full_email,
27
+ :from => email,
28
+ :to => [],
29
+ :server => ENV['SMTPSERVER'] || 'localhost:25',
30
+ :body => STDIN
31
+ )
32
+ string_args, hash_args = args.partition { |x| x.is_a?(String) }
33
+ hash_args.each do |hash|
34
+ raise ArgumentError, "Bad argument #{hash}" unless hash.is_a?(Hash)
35
+ hash.each do |k,v|
36
+ options.send("#{k}=", v)
37
+ end
38
+ end
39
+ OptionParser.new do |opts|
40
+ opts.separator ''
41
+ opts.on('-b', '--body FILE', 'Choose a file for the mail body') do |aFile|
42
+ options.body = File.open(aFile)
43
+ end
44
+ opts.on('-t', '--mail-to NAME', 'Choose a recipient') do |aString|
45
+ options.to << aString
46
+ end
47
+ opts.on('-s', '--server NAME:PORT', 'Choose a mail server') do |aString|
48
+ options.server, options.port = aString.split(/:/)
49
+ options.port ||= 25
50
+ end
51
+ opts.on('-S', '--subject NAME', 'Choose your mail subject') do |aString|
52
+ options.subject = aString.sub(/\.?$/, '.')
53
+ end
54
+ opts.on('--[no-]sign', 'Sign the message with gpg') do |signed|
55
+ options.signed = signed
56
+ end
57
+ opts.on('--passphrase FILE', 'the passphrase file') do |aFile|
58
+ options.pass = Pathname.new(aFile)
59
+ end
60
+ opts.on('-a', '--[no-]ask', 'Ask a confirmation before sending') do |ask|
61
+ options.ask = ask
62
+ end
63
+ opts.on('--comment STRING', 'Choose a comment for GPG') do |aComment|
64
+ options.comment = aComment
65
+ end
66
+ opts.on('-m', '--[no-]mime', 'Choose the mime protocole') do |mime|
67
+ options.mime = mime
68
+ end
69
+ opts.on_tail('-h', '--help', 'Show this message') do
70
+ puts opts
71
+ exit
72
+ end
73
+ end.parse!(string_args)
74
+ check_mail_options(options)
75
+ options
76
+ end
77
+
78
+
79
+ def check_mail_options ( options )
80
+ raise ArgumentError, 'No recipents' if options.to.empty?
81
+ raise ArgumentError, 'No mail server' if options.server.nil?
82
+ raise ArgumentError, 'No mail subject' if options.subject.nil?
83
+ end
84
+
85
+ #
86
+ # Mail.
87
+ #
88
+ def sendmail ( *args )
89
+
90
+ body, opts = nil, nil
91
+ if MAIL_FILE.exist?
92
+ STDERR.puts "Using the cache file #{MAIL_FILE}"
93
+ MAIL_FILE.open do |mail_file|
94
+ opts = YAML::chop_header(mail_file)
95
+ body = mail_file.read
96
+ end
97
+ else
98
+ opts = parse_mail_options(*args)
99
+ body = (opts.body.nil?)? '' : opts.body.read
100
+ end
101
+ server, port = opts.server.split(/:/)
102
+ port ||= 25
103
+ STDERR.puts "Smtp Server: #{server}"
104
+
105
+ #
106
+ # Ask the user
107
+ #
108
+ if opts.ask
109
+ require 'ask'
110
+ question = %Q[
111
+ |Send a mail, with this subject: #{opts.subject}
112
+ | to #{opts.to.join(', ')}
113
+ | from #{opts.from_name}
114
+ | #{(opts.signed.nil?)? 'not signed !' : 'signed by ' + opts.from}
115
+ |Are you sure?].head_cut!
116
+ raise 'Aborting' if ask(question, :y) == :n
117
+ end
118
+
119
+ require 'net/smtp'
120
+ Net::SMTP.start(server, port) do |smtp|
121
+ smtp.open_message_stream(opts.from, opts.to) do |f|
122
+ f.print %Q[From: #{opts.from_name}
123
+ |Subject: #{opts.subject}
124
+ |To: #{opts.to.join(', ')}\n].head_cut!
125
+ if opts.signed
126
+ TempPath.new do |mail_body|
127
+ mail_body.open('w') do |out|
128
+ if opts.mime
129
+ out.puts '
130
+ |Content-Type: text/plain; charset=ISO-8859-1; format=flowed
131
+ |Content-Transfer-Encoding: 8bit
132
+ |
133
+ |'.head_cut!
134
+ end
135
+ out.print body
136
+ end
137
+ f.print sign_wrap(opts, mail_body)
138
+ end
139
+ else
140
+ f.print "\n" + body
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+
147
+ def new_id ( n )
148
+ ([0] * n).map!{ |x| "%X" % rand(15) }.join
149
+ end
150
+ protected :new_id
151
+
152
+
153
+ def sign_wrap ( opts, body )
154
+ id = "===============#{new_id 10}==" if opts.mime
155
+
156
+ TempPath.new do |tmp_name|
157
+ tmp_name.open('w') do |tmp|
158
+ if opts.mime
159
+ tmp.print %Q[
160
+ |MIME-Version: 1.0
161
+ |Content-Type: multipart/signed; micalg=pgp-sha1;
162
+ | protocol="application/pgp-signature";
163
+ | boundary="#{id}"
164
+ |Content-Transfer-Encoding: 8bit
165
+ |
166
+ |This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
167
+ |--#{id}
168
+ |].head_cut!
169
+
170
+ tmp.print body.read
171
+
172
+ tmp.print %Q[
173
+ |
174
+ |--#{id}
175
+ |Content-Type: application/pgp-signature; name="signature.asc"
176
+ |Content-Description: OpenPGP digital signature
177
+ |Content-Disposition: attachment; filename="signature.asc"
178
+ |
179
+ |].head_cut!
180
+ end
181
+
182
+ TempPath.new do |tmp_out|
183
+ pid = fork do
184
+ cmd = %w[ gpg --status-fd 2 --sign --textmode --armor
185
+ --digest-algo sha1 --no-use-agent -u ]
186
+ cmd << "<#{opts.from}>"
187
+ cmd << ((opts.mime)? '--detach-sign' : '--clearsign')
188
+ cmd += [ '--output', tmp_out ]
189
+ if opts.pass
190
+ cmd += [ '--no-tty', '--batch',
191
+ '--passphrase-fd', opts.pass.open.to_i.to_s ]
192
+ end
193
+ cmd += [ '--comment', "'#{opts.comment}'" ] if opts.comment
194
+ STDIN.reopen(body.open)
195
+ exec(*cmd)
196
+ end
197
+ Process.waitpid pid
198
+
199
+ tmp.print tmp_out.read
200
+ tmp.puts "\n--#{id}--" if opts.mime
201
+ end
202
+ end
203
+
204
+ return tmp_name.read
205
+ end
206
+ end
207
+
208
+ end # class Sendmail
209
+
210
+
211
+ if $0 == __FILE__
212
+ $: << Pathname.new(__FILE__).dirname.to_s
213
+ Sendmail.new.sendmail(*ARGV)
214
+ end
@@ -0,0 +1,122 @@
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: service_manager.rb 266 2005-06-01 14:27:18Z ertai $
7
+
8
+ require 'ruby_ex'
9
+ require 'drb/drb'
10
+
11
+ # A service must implement at least:
12
+ # - start_service(uri, *args, &block)
13
+ # - stop_service
14
+ # - server
15
+ # - thread
16
+ # - uri
17
+ module ServiceManager
18
+
19
+ def start_service(service, uri=nil, *args, &block)
20
+ @services = {} unless defined? @services
21
+ service.start_service(uri, *args, &block)
22
+ @services[service.uri] = service
23
+ end
24
+
25
+ def stop_service(uri)
26
+ if defined? @services
27
+ if service = @services.delete(uri)
28
+ service.stop_service
29
+ end
30
+ end
31
+ end
32
+
33
+ def stop_services
34
+ if defined? @services
35
+ @services.keys.each do |uri|
36
+ stop_service(uri)
37
+ end
38
+ end
39
+ end
40
+
41
+ def count_services
42
+ if defined? @services
43
+ @services.size
44
+ else
45
+ 0
46
+ end
47
+ end
48
+
49
+ def list_services
50
+ if defined? @services
51
+ @services.values
52
+ else
53
+ []
54
+ end
55
+ end
56
+
57
+ def join_services
58
+ if defined? @services
59
+ @services.each { |uri, service| service.thread.join }
60
+ end
61
+ end
62
+
63
+ def each_services(&block)
64
+ if defined? @services
65
+ @services.each { |uri, service| block[uri, service] }
66
+ end
67
+ end
68
+
69
+ def service_server(uri)
70
+ @services[uri].server if defined? @services
71
+ end
72
+
73
+ end # module ServiceManager
74
+
75
+
76
+ test_section __FILE__ do
77
+
78
+
79
+ require 'drb'
80
+
81
+
82
+ class ServiceManagerTest < Test::Unit::TestCase
83
+
84
+ class Foo
85
+ include ServiceManager
86
+
87
+ end
88
+
89
+ module MyService
90
+
91
+ module_function
92
+ def start_service(uri); end
93
+ def stop_service; end
94
+ def uri; 'toto'; end
95
+
96
+ end
97
+
98
+ def test_simple
99
+ f = Foo.new
100
+ f.start_service(DRb)
101
+ assert_equal(1, f.count_services)
102
+ f.start_service(DRb)
103
+ assert_equal(2, f.count_services)
104
+ f.start_service(MyService)
105
+ [ DRb, DRb, MyService ].each do |s|
106
+ assert(f.list_services.include?(s))
107
+ end
108
+ assert_equal(3, f.count_services)
109
+ f.stop_service(MyService.uri)
110
+ assert_equal(2, f.count_services)
111
+ f.start_service(MyService)
112
+ [ DRb, DRb, MyService ].each do |s|
113
+ assert(f.list_services.include?(s))
114
+ end
115
+ f.stop_services
116
+ assert_equal([], f.list_services)
117
+ end
118
+
119
+ end # class ServiceManagerTest
120
+
121
+ end
122
+
data/src/shuffle.rb ADDED
@@ -0,0 +1,30 @@
1
+ # Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
2
+ # Copyright:: Copyright (c) 2005 Nicolas Pouillard. All rights reserved.
3
+ # License:: GNU General Public License (GPL).
4
+ # Revision:: $Id: shuffle.rb 220 2005-05-09 12:28:26Z ertai $
5
+
6
+ class Array
7
+
8
+ def shuffle! ( generator=nil )
9
+ n = size
10
+ n.times do |i|
11
+ swap!(i, n.choose(generator))
12
+ end
13
+ self
14
+ end
15
+
16
+ def shuffle ( generator=nil )
17
+ dup.shuffle!(generator)
18
+ end
19
+
20
+ def swap! ( i, j )
21
+ self[i], self[j] = self[j], self[i]
22
+ end
23
+
24
+ def swap ( i, j )
25
+ dup.swap!(i, j)
26
+ end
27
+
28
+ end # class Array
29
+
30
+
data/src/spring.rb ADDED
@@ -0,0 +1,134 @@
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: spring.rb 266 2005-06-01 14:27:18Z ertai $
7
+
8
+
9
+ require 'ruby_ex'
10
+ require 'thread'
11
+ require 'observer'
12
+
13
+
14
+ class Spring
15
+
16
+ include Observable
17
+
18
+ GET = :get
19
+ SIGN_UP = :sign_up
20
+
21
+ def initialize(*items)
22
+ @q = *items
23
+ @mutex = Mutex.new
24
+ @collecter = []
25
+ end
26
+
27
+ def get(collecter_id)
28
+ @mutex.synchronize do
29
+ if @collecter.include?(collecter_id)
30
+ item = @q.shift
31
+ changed(true)
32
+ notify_observers(self.object_id, GET, collecter_id)
33
+ return item
34
+ end
35
+ end
36
+ end
37
+
38
+ def size
39
+ @mutex.synchronize { return @q.size }
40
+ end
41
+ alias length size
42
+
43
+ def empty?
44
+ @mutex.synchronize { return @q.empty? }
45
+ end
46
+
47
+ def sign_up(collecter_id)
48
+ @mutex.synchronize do
49
+ unless @collecter.include?(collecter_id)
50
+ @collecter << collecter_id
51
+ changed(true)
52
+ notify_observers(self.object_id, SIGN_UP, collecter_id)
53
+ return nil
54
+ end
55
+ end
56
+ end
57
+
58
+ def num_collecter
59
+ @mutex.synchronize { @collecter.length }
60
+ end
61
+
62
+ end # class Spring
63
+
64
+
65
+ #
66
+ # Unit test suite
67
+ #
68
+ test_section __FILE__ do
69
+
70
+
71
+ class SpringTest < Test::Unit::TestCase
72
+
73
+ class Obs
74
+
75
+ attr_reader :updated, :msg_seq
76
+
77
+ def initialize(s_id, msg_seq, t_id, spring_test_instance)
78
+ @s_id = s_id
79
+ @msg_seq = msg_seq
80
+ @t_id = t_id
81
+ @updated = false
82
+ @spring_test_instance = spring_test_instance
83
+ end
84
+
85
+ def update(s_id, msg, t_id)
86
+ @updated = true
87
+ @spring_test_instance.test_update(@s_id,
88
+ @msg_seq,
89
+ @t_id,
90
+ s_id,
91
+ msg,
92
+ t_id)
93
+ end
94
+
95
+ end
96
+
97
+ #
98
+ # tests
99
+ #
100
+ def test_simple
101
+ s = Spring.new('hello', 'world')
102
+ q = Queue.new
103
+ thread = Thread.new do
104
+ s.add_observer(q.pop)
105
+ assert_equal(2, s.size)
106
+ assert_equal(2, s.length)
107
+ assert_nil(s.get(thread.object_id))
108
+ s.sign_up(thread.object_id)
109
+ assert_equal(1, s.num_collecter)
110
+ assert_equal('hello', s.get(thread.object_id))
111
+ assert_equal('world', s.get(thread.object_id))
112
+ end
113
+ o = Obs.new(s.object_id,
114
+ [Spring::SIGN_UP, Spring::GET, Spring::GET],
115
+ thread.object_id,
116
+ self)
117
+ q.push(o)
118
+ thread.join
119
+ assert_equal(true, o.updated, 'not visited at all')
120
+ assert_equal([], o.msg_seq)
121
+ end
122
+
123
+ # tools
124
+
125
+ def test_update(r_s_id, r_msg, r_t_id, s_id, msg, t_id)
126
+ assert_equal(r_t_id, t_id, 'bad collecter id')
127
+ assert_equal(r_s_id, s_id, 'bad spring id')
128
+ assert_equal(r_msg.shift, msg, 'bad message')
129
+ end
130
+
131
+ end # class SpringTest
132
+
133
+
134
+ end