vcs 0.1 → 0.2.148

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. data/Rakefile +17 -3
  2. data/bin/vcs +57 -34
  3. data/doc/jamis.rb +564 -0
  4. data/ruby_ex/abstract.rb +254 -0
  5. data/ruby_ex/abstract_node.rb +85 -0
  6. data/ruby_ex/algorithms/simulated_annealing.rb +140 -0
  7. data/ruby_ex/array_each_pair.rb +18 -0
  8. data/ruby_ex/ask.rb +101 -0
  9. data/ruby_ex/attributed_class.rb +302 -0
  10. data/ruby_ex/cache.rb +373 -0
  11. data/ruby_ex/checkout.rb +12 -0
  12. data/ruby_ex/choose.rb +271 -0
  13. data/ruby_ex/commands.rb +18 -0
  14. data/ruby_ex/commands/command.rb +401 -0
  15. data/ruby_ex/commands/datas.rb +16 -0
  16. data/ruby_ex/commands/datas/data.rb +33 -0
  17. data/ruby_ex/commands/datas/factory.rb +66 -0
  18. data/ruby_ex/commands/factory.rb +66 -0
  19. data/ruby_ex/commands/helpers.rb +67 -0
  20. data/ruby_ex/commands/pipe.rb +64 -0
  21. data/ruby_ex/commands/runners.rb +17 -0
  22. data/ruby_ex/commands/runners/exec.rb +49 -0
  23. data/ruby_ex/commands/runners/fork.rb +97 -0
  24. data/ruby_ex/commands/runners/runner.rb +107 -0
  25. data/ruby_ex/commands/seq.rb +27 -0
  26. data/ruby_ex/config_file.rb +96 -0
  27. data/ruby_ex/const_regexp.rb +59 -0
  28. data/ruby_ex/daemon.rb +134 -0
  29. data/ruby_ex/diff.rb +667 -0
  30. data/ruby_ex/dlogger.rb +62 -0
  31. data/ruby_ex/drb/dispatcher.rb +252 -0
  32. data/ruby_ex/drb/dispatcher_server_test.rb +29 -0
  33. data/ruby_ex/drb/drb_observable.rb +97 -0
  34. data/ruby_ex/drb/drb_observable_pool.rb +27 -0
  35. data/ruby_ex/drb/drb_service.rb +43 -0
  36. data/ruby_ex/drb/drb_undumped_attributes.rb +55 -0
  37. data/ruby_ex/drb/drb_undumped_indexed_object.rb +54 -0
  38. data/ruby_ex/drb/insecure_protected_methods.rb +103 -0
  39. data/ruby_ex/drb/session_client_test.rb +40 -0
  40. data/ruby_ex/drb/session_manager.rb +246 -0
  41. data/ruby_ex/drb/session_server.rb +53 -0
  42. data/ruby_ex/dtime.rb +143 -0
  43. data/ruby_ex/dumpable_proc.rb +63 -0
  44. data/ruby_ex/exception.rb +32 -0
  45. data/ruby_ex/filetype.rb +229 -0
  46. data/ruby_ex/fileutils_ex.rb +44 -0
  47. data/ruby_ex/fold.rb +58 -0
  48. data/ruby_ex/generate_id.rb +44 -0
  49. data/ruby_ex/hookable.rb +262 -0
  50. data/ruby_ex/hooker.rb +54 -0
  51. data/ruby_ex/inactive_timeout.rb +137 -0
  52. data/ruby_ex/indexed_node.rb +66 -0
  53. data/ruby_ex/io_marshal.rb +100 -0
  54. data/ruby_ex/ioo.rb +194 -0
  55. data/ruby_ex/labeled_node.rb +63 -0
  56. data/ruby_ex/logger_observer.rb +23 -0
  57. data/ruby_ex/md5sum.rb +66 -0
  58. data/ruby_ex/mktemp.rb +208 -0
  59. data/ruby_ex/module/attr_once.rb +36 -0
  60. data/ruby_ex/module/autoload_tree.rb +75 -0
  61. data/ruby_ex/module/hierarchy.rb +335 -0
  62. data/ruby_ex/module/instance_method_visibility.rb +73 -0
  63. data/ruby_ex/module_ex.rb +11 -0
  64. data/ruby_ex/node.rb +80 -0
  65. data/ruby_ex/object_monitor.rb +145 -0
  66. data/ruby_ex/object_monitor_activity.rb +33 -0
  67. data/ruby_ex/observable.rb +140 -0
  68. data/ruby_ex/observable_pool.rb +293 -0
  69. data/ruby_ex/orderedhash.rb +252 -0
  70. data/ruby_ex/pathname_ex.rb +152 -0
  71. data/ruby_ex/pp_hierarchy.rb +29 -0
  72. data/ruby_ex/pseudo_cache.rb +190 -0
  73. data/ruby_ex/queue.rb +56 -0
  74. data/ruby_ex/random_generators.rb +25 -0
  75. data/ruby_ex/random_generators/random_generator.rb +31 -0
  76. data/ruby_ex/random_generators/ruby.rb +23 -0
  77. data/ruby_ex/safe_eval.rb +348 -0
  78. data/ruby_ex/sendmail.rb +215 -0
  79. data/ruby_ex/service_manager.rb +121 -0
  80. data/ruby_ex/session/administrable.rb +120 -0
  81. data/ruby_ex/session/client.rb +153 -0
  82. data/ruby_ex/session/const.rb +18 -0
  83. data/ruby_ex/session/dispatcher.rb +184 -0
  84. data/ruby_ex/session/error.rb +21 -0
  85. data/ruby_ex/session/fetchable.rb +57 -0
  86. data/ruby_ex/session/fetcher.rb +62 -0
  87. data/ruby_ex/session/hookable.rb +26 -0
  88. data/ruby_ex/session/profile.rb +110 -0
  89. data/ruby_ex/session/server.rb +582 -0
  90. data/ruby_ex/session/test/administrable_test.rb +337 -0
  91. data/ruby_ex/session/test/basic_test.rb +523 -0
  92. data/ruby_ex/session/test/dispatcher_test.rb +409 -0
  93. data/ruby_ex/session/test/fetchable_test.rb +119 -0
  94. data/ruby_ex/session/test/sub_server_test.rb +188 -0
  95. data/ruby_ex/shuffle.rb +30 -0
  96. data/ruby_ex/spring.rb +136 -0
  97. data/ruby_ex/spring_set.rb +137 -0
  98. data/ruby_ex/string_ex.rb +28 -0
  99. data/ruby_ex/symtbl.rb +106 -0
  100. data/ruby_ex/synflow.rb +474 -0
  101. data/ruby_ex/test/unit/ui/yaml/testrunner.rb +164 -0
  102. data/ruby_ex/thread_mutex.rb +10 -0
  103. data/ruby_ex/timeout_ex.rb +81 -0
  104. data/ruby_ex/top_down.rb +73 -0
  105. data/ruby_ex/trace.rb +26 -0
  106. data/ruby_ex/uri/druby.rb +81 -0
  107. data/ruby_ex/uri/file.rb +65 -0
  108. data/ruby_ex/uri/ftp_ex.rb +37 -0
  109. data/ruby_ex/uri/http_ex.rb +43 -0
  110. data/ruby_ex/uri/ssh.rb +92 -0
  111. data/ruby_ex/uri/svn.rb +118 -0
  112. data/ruby_ex/uri_ex.rb +45 -0
  113. data/ruby_ex/verbose_object.rb +30 -0
  114. data/ruby_ex/version.rb +66 -0
  115. data/ruby_ex/yaml/basenode_ext.rb +63 -0
  116. data/ruby_ex/yaml/chop_header.rb +23 -0
  117. data/ruby_ex/yaml/transform.rb +449 -0
  118. data/ruby_ex/yaml/yregexpath.rb +76 -0
  119. data/src/changelog.rb +28 -18
  120. data/src/conflict.rb +20 -0
  121. data/src/diff.rb +18 -0
  122. data/src/diffstat.rb +9 -3
  123. data/src/last_changed_date.rb +18 -0
  124. data/src/mail.rb +33 -65
  125. data/src/message.rb +15 -9
  126. data/src/mycommit.rb +29 -14
  127. data/src/news.rb +24 -3
  128. data/src/status.rb +17 -0
  129. data/src/svn.rb +2 -2
  130. data/src/vcs.rb +24 -3
  131. metadata +124 -5
  132. data/lrdetools.rb +0 -12
@@ -0,0 +1,12 @@
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: checkout.rb 159 2005-02-18 12:07:23Z polrop $
7
+
8
+ require 'uri_ex'
9
+ require 'uri/http_ex'
10
+ require 'uri/ftp_ex'
11
+ require 'uri/file'
12
+ require 'uri/svn'
@@ -0,0 +1,271 @@
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: choose.rb 219 2005-05-09 12:26:29Z ertai $
5
+
6
+
7
+ require 'random_generators'
8
+
9
+
10
+ class Integer
11
+
12
+ def self.choose ( limit=nil, generator=nil )
13
+ limit.to_i.choose(generator)
14
+ end
15
+
16
+ def choose ( generator=nil )
17
+ (generator || RandomGenerators.default).choose_integer(self)
18
+ end
19
+
20
+ end # class Integer
21
+
22
+
23
+
24
+ class Float
25
+
26
+ def self.choose ( limit=nil, generator=nil )
27
+ (limit || 1.0).to_f.choose(generator)
28
+ end
29
+
30
+ def choose ( generator=nil )
31
+ (generator || RandomGenerators.default).choose_float(self)
32
+ end
33
+
34
+ end # class Float
35
+
36
+
37
+
38
+ class Hash
39
+
40
+ def choose ( limit=nil, generator=nil )
41
+ self[keys.choose(limit, generator)]
42
+ end
43
+
44
+ end # class Hash
45
+
46
+
47
+
48
+ class Array
49
+
50
+ def choose ( limit=nil, generator=nil )
51
+ n = size
52
+
53
+ # Out of limits: limit > size (FIXME warn)
54
+ limit = n if limit.nil? or limit > n
55
+
56
+ self[limit.choose(generator)]
57
+ end
58
+
59
+ end # class Array
60
+
61
+
62
+
63
+ module Enumerable
64
+
65
+ def choose ( limit=nil, generator=nil )
66
+ to_a.choose(limit, generator)
67
+ end
68
+
69
+ end # module Enumerable
70
+
71
+
72
+
73
+ class Range
74
+
75
+ def choose ( generator=nil )
76
+ case first
77
+ when Integer
78
+ first + (last + 1 - first).choose(generator)
79
+ else
80
+ super(nil, generator)
81
+ end
82
+ end
83
+
84
+ end # class Array
85
+
86
+
87
+
88
+ if $0 == __FILE__
89
+
90
+ class MockRandomGenerator < RandomGenerators::RandomGenerator
91
+ concrete
92
+ attr_reader :ref
93
+ def initialize ( tab_i, tab_f )
94
+ raise unless tab_i.is_a? Array
95
+ raise unless tab_f.is_a? Array
96
+ @ref, @ref_f, @pos = tab_i, tab_f, -1
97
+ end
98
+ def get ( tab )
99
+ tab[@pos = (@pos + 1) % tab.size]
100
+ end
101
+ def choose_integer ( n )
102
+ check_choose_integer(n)
103
+ get(@ref) % n
104
+ end
105
+ def choose_float ( f=1.0 )
106
+ check_choose_float(f)
107
+ get(@ref_f) * f
108
+ end
109
+ end # class MockRandomGenerator
110
+
111
+ class RandomMockRandomGenerator < MockRandomGenerator
112
+ def initialize ( n )
113
+ tab_i = (0 .. n - 1).to_a.shuffle
114
+ tab_f = []
115
+ n.times { tab_f << Float.choose() }
116
+ super(tab_i, tab_f)
117
+ end
118
+ end # class RandomMockRandomGenerator
119
+
120
+
121
+ require 'test/unit'
122
+ require 'set'
123
+
124
+ class ChooseTest < Test::Unit::TestCase
125
+
126
+ REF_5 = [1, 2, 4, 0, 3]
127
+ REF_F_5 = [0.187528345035389, 0.368857819121331, 0.06954449811019,
128
+ 0.188887464581057, 0.213757352204993]
129
+ REF_50 = [
130
+ 28, 12, 17, 10, 1, 37, 46, 25, 47, 2, 45, 36, 20, 5, 30, 14, 18, 39,
131
+ 8, 15, 16, 43, 27, 33, 22, 7, 32, 3, 35, 9, 19, 13, 21, 6, 23, 26, 4,
132
+ 40, 44, 11, 49, 29, 42, 24, 31, 48, 34, 0, 38, 41
133
+ ]
134
+ REF_F_50 = [
135
+ 0.643785412423313, 0.765736325876787, 0.604515956481919,
136
+ 0.133839202811942, 0.350400971015915, 0.966710213804618,
137
+ 0.904755113180727, 0.88459848286584, 0.163951952941716,
138
+ 0.808023529592901, 0.387806572020054, 0.659689131658524,
139
+ 0.289974238490686, 0.813535830006003, 0.565311754588038,
140
+ 0.889200099511072, 0.0668127918615937, 0.992091996129602,
141
+ 0.604403987759724, 0.89254002738744, 0.601499371463433,
142
+ 0.754795648856089, 0.751190354581922, 0.434389552799985,
143
+ 0.761369747575372, 0.174903159961104, 0.940325234550983,
144
+ 0.536097376374528, 0.957906004507095, 0.693120914744213,
145
+ 0.23448576242663, 0.638284107437357, 0.423910334473476,
146
+ 0.251349127152935, 0.457931924844161, 0.20579389645718,
147
+ 0.256057573715225, 0.584466924890876, 0.609375598141924,
148
+ 0.0856487881392241, 0.437958877766505, 0.432312048738822,
149
+ 0.81560374982655, 0.142059376928955, 0.118824432371184,
150
+ 0.958816710859537, 0.69899930502288, 0.118259542621672,
151
+ 0.52218786906451, 0.339233995880932
152
+ ]
153
+
154
+ def checker_n ( n, ref_i, ref_f, inp, ref, lim=nil )
155
+ mrg = MockRandomGenerator.new(ref_i, ref_f)
156
+ my = []
157
+ if lim == :no
158
+ n.times { my << inp.choose(mrg) }
159
+ else
160
+ n.times { my << inp.choose(lim, mrg) }
161
+ end
162
+ assert_equal(ref, my)
163
+ end
164
+
165
+ def checker_5 ( inp, ref, lim=nil )
166
+ checker_n(5, REF_5, REF_F_5, inp, ref, lim)
167
+ end
168
+
169
+ def checker_50 ( inp, ref, lim=nil )
170
+ checker_n(50, REF_50, REF_F_50, inp, ref, lim)
171
+ end
172
+
173
+
174
+
175
+
176
+ def test_integer
177
+ checker_5 Integer, REF_5, 5
178
+ checker_50 Integer, REF_50, 50
179
+ assert(Integer.choose(1000) < 1000)
180
+ end
181
+
182
+ def test_float
183
+ checker_5 Float, REF_F_5, 1.0
184
+ checker_50 Float, REF_F_50, 1.0
185
+ assert(Float.choose(2.0) < 2)
186
+ assert(Float.choose < 1)
187
+ end
188
+
189
+ def test_array_5
190
+ checker_5 [4], [4] * 5, 5
191
+ checker_5 [4, 5], [5, 4, 4, 4, 5], 5
192
+ checker_5 [4, 5, 6], [5, 6, 5, 4, 4], 5
193
+ checker_5 [2, 1, 0, 5, 4, 3], [1, 0, 4, 2, 5], 5
194
+ 10.times { assert(REF_50.include?(REF_50.choose)) }
195
+ end
196
+
197
+ def test_set_5
198
+ checker_5 Set[4], [4] * 5, 5
199
+ checker_5 Set[4, 5], [4, 5, 5, 5, 4], 5
200
+ checker_5 Set[4, 5, 6], [6, 4, 6, 5, 5], 5
201
+ checker_5 Set[2, 1, 0, 5, 4, 3], [0, 1, 3, 5, 2], 5
202
+ set = REF_50.to_set
203
+ 10.times { assert(set.include?(set.choose)) }
204
+ end
205
+
206
+ def test_hash
207
+ checker_5({ 1 => 2 }, [2] * 5, 5)
208
+ checker_5({ 1 => 2, 3 => 4 }, [4, 2, 2, 2, 4], 5)
209
+ end
210
+
211
+ def test_array_50
212
+ checker_50 [4], [4] * 50, 50
213
+ checker_50 [
214
+ 36, 16, 15, 6, 27, 33, 17, 10, 18, 39, 8, 43, 19, 23, 49, 40, 46, 37,
215
+ 9, 41, 35, 0, 38, 26, 22, 4, 7, 25, 21, 12, 42, 45, 28, 5, 31, 24, 34,
216
+ 48, 32, 30, 13, 29, 11, 2, 1, 20, 3, 44, 47, 14
217
+ ], [
218
+ 21, 19, 37, 8, 16, 48, 3, 4, 44, 15, 20, 34, 35, 33, 42, 49, 9, 30,
219
+ 18, 40, 46, 2, 25, 5, 38, 10, 28, 6, 24, 39, 41, 23, 0, 17, 26, 7, 27,
220
+ 13, 1, 43, 14, 12, 11, 22, 45, 47, 31, 36, 32, 29
221
+ ], 50
222
+ end
223
+
224
+ def test_integer_instances
225
+ assert_raise(ArgumentError) { checker_5 0, [], :no }
226
+ checker_5 1, [0] * 5, :no
227
+ checker_5 4, [1, 2, 0, 0, 3], :no
228
+ checker_5 10, REF_5, :no
229
+ assert(1000.choose < 1000)
230
+ end
231
+
232
+ def test_float_instances
233
+ assert_raise(ArgumentError) { checker_5 0.0, [], :no }
234
+ checker_5 1.0, [ 0.187528345035389, 0.368857819121331, 0.06954449811019,
235
+ 0.188887464581057, 0.213757352204993 ], :no
236
+ assert(2.0.choose < 2)
237
+ end
238
+
239
+ def test_integer_range_instances
240
+ checker_5 1..1, [1] * 5, :no
241
+ checker_5 1..2, [2, 1, 1, 1, 2], :no
242
+ checker_5 0..1, [1, 0, 0, 0, 1], :no
243
+ checker_5 0..4, [1, 2, 4, 0, 3], :no
244
+ end
245
+
246
+ class Xs
247
+ include Comparable
248
+ attr_reader :length
249
+ def initialize ( n )
250
+ @length = n
251
+ end
252
+ def succ
253
+ Xs.new(@length.succ)
254
+ end
255
+ def <=> ( rhs )
256
+ @length <=> rhs.length
257
+ end
258
+ def inspect
259
+ 'x' * @length
260
+ end
261
+ end
262
+
263
+ def test_range_instances
264
+ checker_5 'a'..'a', ['a'] * 5, :no
265
+ checker_5 'a'..'b', ['b', 'a', 'a', 'a', 'b'], :no
266
+ checker_5 Xs.new(1)..Xs.new(4), [2, 3, 1, 1, 4].map { |x| Xs.new(x) }, :no
267
+ end
268
+
269
+ end # class ChooseTest
270
+
271
+ end
@@ -0,0 +1,18 @@
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: commands.rb 221 2005-05-09 12:40:57Z ertai $
5
+
6
+ require 'module/autoload_tree'
7
+ require 'pathname_ex'
8
+ require 'abstract'
9
+ require 'commands/helpers'
10
+ require 'mktemp'
11
+ require 'commands/runners'
12
+
13
+
14
+ module Commands
15
+
16
+ autoloaded_module(__FILE__)
17
+
18
+ end # module Commands
@@ -0,0 +1,401 @@
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: command.rb 221 2005-05-09 12:40:57Z ertai $
5
+
6
+ module Commands
7
+
8
+ class Command
9
+
10
+ attr_accessor :command
11
+ attr_accessor :dir
12
+ attr_accessor :input
13
+ attr_accessor :output
14
+ attr_accessor :error
15
+ attr_accessor :arg_list
16
+
17
+ #
18
+ # Construction methods.
19
+ #
20
+
21
+ def initialize ( command_name, *args )
22
+ @command = command_name
23
+ @arg_list = args.dup
24
+ end
25
+
26
+ #
27
+ # Command['wc -l'].sh
28
+ #
29
+ def self.[] ( *args )
30
+ new(*args)
31
+ end
32
+
33
+
34
+
35
+ #
36
+ # Running methods.
37
+ #
38
+
39
+ # Simulate Kernel#system() to run the command (No shell expansion).
40
+ def system
41
+ unless defined? @@fork_runner
42
+ @@fork_runner = Runners::Fork.new
43
+ end
44
+ run(@@fork_runner)
45
+ end
46
+
47
+
48
+ # Use the ExecRunner.
49
+ def exec
50
+ unless defined? @@exec_runner
51
+ @@exec_runner = Runners::Exec.new
52
+ end
53
+ run(@@exec_runner)
54
+ end
55
+
56
+
57
+ # Use Kernel#system() but with a string to have the shell expansion.
58
+ def sh
59
+ Kernel.system(to_sh)
60
+ end
61
+
62
+
63
+ # Use Kernel#exec() but with a string to have the shell expansion.
64
+ def sh!
65
+ Kernel.exec(to_sh)
66
+ end
67
+
68
+
69
+ # Use Kernel#` and return the resulting string.
70
+ def expand
71
+ `#{to_sh}`
72
+ end
73
+
74
+
75
+ # FIXME design me!
76
+ def ruby
77
+ end
78
+
79
+
80
+ # Use a Commands::Runners::Runner and return a Commands::Datas::Data.
81
+ def run ( runner=@runner )
82
+ runner.run(self)
83
+ end
84
+
85
+
86
+
87
+ #
88
+ # Operators.
89
+ #
90
+
91
+
92
+ # Pipe two commands.
93
+ def | ( rhs )
94
+ Pipe.new(self, rhs)
95
+ end
96
+
97
+
98
+ # Chain two commands (like a `;' in shell), and return a new one.
99
+ def + ( rhs )
100
+ Seq.new(self, rhs)
101
+ end
102
+
103
+
104
+ # Return a new command with the given command input.
105
+ def < ( arg )
106
+ cmd = dup
107
+ cmd.input = arg
108
+ cmd
109
+ end
110
+
111
+
112
+ # Return a new command with the given command output.
113
+ def > ( arg )
114
+ cmd = dup
115
+ cmd.output = arg.dup
116
+ cmd.output.open_mode = 'w' if cmd.output.is_a? Pathname
117
+ cmd
118
+ end
119
+
120
+
121
+ # Like > but open the output in append mode.
122
+ def >> ( arg )
123
+ cmd = dup
124
+ cmd.output = arg.dup
125
+ cmd.output.open_mode = 'a' if cmd.output.is_a? Pathname
126
+ cmd
127
+ end
128
+
129
+
130
+ # Add an argument to a command.
131
+ # cmd = Command.new('ls')
132
+ # cmd << '-la'
133
+ # cmd.sh
134
+ def << ( arg )
135
+ @arg_list << arg
136
+ end
137
+
138
+
139
+
140
+ #
141
+ # Misc
142
+ #
143
+
144
+ def arg_list
145
+ @arg_list.dup
146
+ end
147
+
148
+
149
+ def arg_string
150
+ @arg_list.map { |arg| arg.dump }.join(' ').freeze
151
+ end
152
+
153
+
154
+ #
155
+ # Conversion methods
156
+ #
157
+
158
+ def to_s
159
+ str = @command.dump
160
+ arg_str = arg_string
161
+ str += ' ' + arg_str unless arg_str.empty?
162
+ str
163
+ end
164
+
165
+
166
+ def to_sh
167
+ "#{to_s}#{sh_args}"
168
+ end
169
+
170
+
171
+ def sh_args
172
+ args = ''
173
+ args += " < #{@input.to_s.dump}" if @input
174
+ args += " > #{@output.to_s.dump}" if @output
175
+ args += " 2> #{@error.to_s.dump}" if @error
176
+ args
177
+ end
178
+
179
+
180
+ def to_a
181
+ [@command, *@arg_list].freeze
182
+ end
183
+
184
+ end # class Command
185
+
186
+ if $0 == __FILE__
187
+ require 'test/unit'
188
+
189
+ class CommandTest < Test::Unit::TestCase
190
+
191
+ def setup
192
+ @file = TempPath.new
193
+ @file.open('w') { |f| f.puts "bla bla\n foo bar"}
194
+ ENV['TEST_FILE'] = @file.to_s
195
+ @touch = Command.new('touch')
196
+ @cp = Command.new('cp')
197
+ @cat = Command.new('cat')
198
+ @wc = Command.new('wc')
199
+ @dne = Command.new('ThisCommandDoesNotExist')
200
+ @dev_null = Pathname.new('/dev/null')
201
+ end
202
+
203
+ def test_0_initialize
204
+ end
205
+
206
+ def test_self_hook # test_self.[]
207
+ @cat << 'foo' << 'bar'
208
+ assert_equal(@cat.to_a, Command[*%w[cat foo bar]].to_a)
209
+ end
210
+
211
+ def test_system
212
+ TempPath.new do |tmp|
213
+ @touch << tmp.to_s
214
+ @touch.system
215
+ assert_equal(0, $?)
216
+ assert(tmp.exist?)
217
+ end
218
+ end
219
+
220
+ def test_sh_and_pipe
221
+ TempPath.new do |tmp|
222
+ ((@cat | @wc) < @file > tmp).sh
223
+ assert_equal(0, $?)
224
+ assert(tmp.exist?)
225
+ assert_match(/\s*2\s*4\s*17\n/, tmp.read)
226
+ end
227
+ end
228
+
229
+ def test_system_and_pipe
230
+ TempPath.new do |tmp|
231
+ ((@cat | @wc) < @file.open('r+') > tmp).system
232
+ assert_equal(0, $?)
233
+ assert(tmp.exist?)
234
+ assert_match(/\s*2\s*4\s*17\n/, tmp.read)
235
+ end
236
+ end
237
+
238
+ def test_system_is_not_sh
239
+ TempPath.new do |tmp|
240
+ @cat << '$TEST_FILE'
241
+ @cat.error = @dev_null
242
+ (@cat > tmp).system
243
+ assert_not_equal(0, $?)
244
+ assert(!tmp.exist? || tmp.zero?)
245
+ end
246
+ end
247
+
248
+ def test_exec
249
+ TempPath.new do |tmp|
250
+ @cp << @file << tmp
251
+ pid = fork do
252
+ @cp.exec
253
+ end
254
+ Process.waitpid pid
255
+ assert_equal(0, $?)
256
+ assert(tmp.exist?)
257
+ assert_equal(@file.read, tmp.read)
258
+ end
259
+ end
260
+
261
+ def test_exec_not_sh!
262
+ TempPath.new do |tmp|
263
+ @cat << '$TEST_FILE'
264
+ @cat.error = @dev_null
265
+ pid = fork do
266
+ (@cat > tmp).exec
267
+ end
268
+ Process.waitpid pid
269
+ assert_not_equal(0, $?)
270
+ assert(!tmp.exist? || tmp.size.zero?)
271
+ end
272
+ end
273
+
274
+ def test_sh
275
+ TempPath.new do |tmp|
276
+ @cat << '$TEST_FILE'
277
+ (@cat > tmp).sh
278
+ assert_equal(0, $?)
279
+ assert(tmp.exist?)
280
+ assert_equal(@file.read, tmp.read)
281
+ end
282
+
283
+ TempPath.new do |tmp|
284
+ ((@cat | @wc) < @file > tmp).sh
285
+ assert_equal(0, $?)
286
+ assert(tmp.exist?)
287
+ assert_match(/\s*2\s*4\s*17\n/, tmp.read)
288
+ end
289
+ end
290
+
291
+ def test_sh!
292
+ TempPath.new do |tmp|
293
+ @cat << '$TEST_FILE'
294
+ pid = fork do
295
+ (@cat > tmp).sh!
296
+ end
297
+ Process.waitpid pid
298
+ assert_equal(0, $?)
299
+ assert(tmp.exist?)
300
+ assert_equal(@file.read, tmp.read)
301
+ end
302
+ end
303
+
304
+ def test_expand
305
+ @cat << '$TEST_FILE'
306
+ str = (@cat).expand
307
+ assert_equal(0, $?)
308
+ assert_equal(@file.read, str)
309
+
310
+ str = ((@cat | @wc) < @file).expand
311
+ assert_equal(0, $?)
312
+ assert_match(/\s*2\s*4\s*17\n/, str)
313
+ end
314
+
315
+ def test_ruby
316
+ # FIXME
317
+ end
318
+
319
+ def test_pipe # test_|
320
+ assert_kind_of(Pipe, (@cat | @wc) < @file)
321
+ end
322
+
323
+ def test_chain # test_+
324
+ assert_kind_of(Seq, (@cat + @wc) < @file)
325
+ TempPath.new do |tmp|
326
+ TempPath.new do |tmp2|
327
+ ((@cat < @file > tmp) + (@wc < tmp > tmp2)).sh
328
+ assert_equal(0, $?)
329
+ assert(tmp.exist?)
330
+ assert(tmp2.exist?)
331
+ assert_equal(@file.read, tmp.read)
332
+ assert_match(/\s*2\s*4\s*17\n/, tmp2.read)
333
+ end
334
+ end
335
+ end
336
+
337
+ def test_add_input # test_<
338
+ @cat.input = 'foo'
339
+ assert_equal('foo', @cat.input)
340
+ cmd = @cat < 'bar'
341
+ assert_equal('bar', cmd.input)
342
+ assert_not_equal(cmd.object_id, @bar.object_id)
343
+ end
344
+
345
+ def test_add_output # test_>
346
+ @cat.output = 'foo'
347
+ assert_equal('foo', @cat.output)
348
+ cmd = @cat > 'bar'
349
+ assert_equal('bar', cmd.output)
350
+ assert_not_equal(cmd.object_id, @bar.object_id)
351
+ end
352
+
353
+ def test_append_output # test_>>
354
+ @cat.output = 'foo'
355
+ assert_equal('foo', @cat.output)
356
+ cmd = @cat >> 'bar'
357
+ assert_equal('bar', cmd.output)
358
+ assert_not_equal(cmd.object_id, @bar.object_id)
359
+ end
360
+
361
+ def test_arg_list
362
+ assert_equal([], @cp.arg_list)
363
+ @cat << 'foo bar' << 'baz'
364
+ assert_equal(['foo bar', 'baz'], @cat.arg_list)
365
+ end
366
+
367
+ def test_arg_string
368
+ assert_equal('', @cp.arg_string)
369
+ @cat << 'foo bar' << 'baz'
370
+ assert_equal('"foo bar" "baz"', @cat.arg_string)
371
+ end
372
+
373
+ def test_to_s
374
+ assert_equal('"cp"', @cp.to_s)
375
+ @cat << 'foo bar' << 'baz'
376
+ assert_equal('"cat" "foo bar" "baz"', @cat.to_s)
377
+ end
378
+
379
+ def test_to_sh
380
+ assert_equal('"cp" > "ya"', (@cp > 'ya').to_sh)
381
+ @cat << 'foo > bar' << '< baz'
382
+ assert_equal(
383
+ '(("cat" "foo > bar" "< baz" < "yay") | ("cp" > "yoy"))',
384
+ ((@cat | @cp) < 'yay' > 'yoy').to_sh)
385
+ @wc.error = 'foo'
386
+ assert_equal('"wc" 2> "foo"', @wc.to_sh)
387
+ end
388
+
389
+ def test_complex
390
+ TempPath.new do |tmp|
391
+ ls = 'ls'.to_cmd
392
+ wc = 'wc'.to_cmd
393
+ (ls | wc) < @file > tmp
394
+ end
395
+ end
396
+
397
+ end # class CommandTest
398
+
399
+ end
400
+
401
+ end # module Commands