ruby_ex 0.1.1

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.
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