engineyard-serverside 1.2.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.
Files changed (220) hide show
  1. data/LICENSE +19 -0
  2. data/bin/engineyard-serverside +10 -0
  3. data/lib/engineyard-serverside.rb +49 -0
  4. data/lib/engineyard-serverside/bundle_installer.rb +4 -0
  5. data/lib/engineyard-serverside/cli.rb +146 -0
  6. data/lib/engineyard-serverside/configuration.rb +130 -0
  7. data/lib/engineyard-serverside/default_maintenance_page.html +29 -0
  8. data/lib/engineyard-serverside/deploy.rb +321 -0
  9. data/lib/engineyard-serverside/deploy_hook.rb +80 -0
  10. data/lib/engineyard-serverside/lockfile_parser.rb +55 -0
  11. data/lib/engineyard-serverside/logged_output.rb +78 -0
  12. data/lib/engineyard-serverside/server.rb +70 -0
  13. data/lib/engineyard-serverside/strategies/git.rb +136 -0
  14. data/lib/engineyard-serverside/task.rb +62 -0
  15. data/lib/engineyard-serverside/version.rb +3 -0
  16. data/lib/vendor/dataflow/HISTORY +52 -0
  17. data/lib/vendor/dataflow/LICENSE +19 -0
  18. data/lib/vendor/dataflow/README.textile +290 -0
  19. data/lib/vendor/dataflow/Rakefile +36 -0
  20. data/lib/vendor/dataflow/dataflow.rb +120 -0
  21. data/lib/vendor/dataflow/dataflow/actor.rb +22 -0
  22. data/lib/vendor/dataflow/dataflow/equality.rb +28 -0
  23. data/lib/vendor/dataflow/dataflow/future_queue.rb +24 -0
  24. data/lib/vendor/dataflow/dataflow/port.rb +54 -0
  25. data/lib/vendor/dataflow/examples/barrier.rb +9 -0
  26. data/lib/vendor/dataflow/examples/data_driven.rb +17 -0
  27. data/lib/vendor/dataflow/examples/dataflow_http_gets.rb +13 -0
  28. data/lib/vendor/dataflow/examples/flow.rb +20 -0
  29. data/lib/vendor/dataflow/examples/future_http_gets.rb +12 -0
  30. data/lib/vendor/dataflow/examples/future_queue.rb +11 -0
  31. data/lib/vendor/dataflow/examples/instance_variables.rb +15 -0
  32. data/lib/vendor/dataflow/examples/laziness.rb +9 -0
  33. data/lib/vendor/dataflow/examples/local_variables.rb +11 -0
  34. data/lib/vendor/dataflow/examples/messages.rb +26 -0
  35. data/lib/vendor/dataflow/examples/port_http_gets.rb +13 -0
  36. data/lib/vendor/dataflow/examples/port_send.rb +10 -0
  37. data/lib/vendor/dataflow/examples/ring.rb +21 -0
  38. data/lib/vendor/dataflow/spec/actor_spec.rb +28 -0
  39. data/lib/vendor/dataflow/spec/anonymous_variables_spec.rb +21 -0
  40. data/lib/vendor/dataflow/spec/barrier_spec.rb +25 -0
  41. data/lib/vendor/dataflow/spec/by_need_spec.rb +55 -0
  42. data/lib/vendor/dataflow/spec/dataflow_spec.rb +151 -0
  43. data/lib/vendor/dataflow/spec/equality_spec.rb +40 -0
  44. data/lib/vendor/dataflow/spec/flow_spec.rb +25 -0
  45. data/lib/vendor/dataflow/spec/forker_spec.rb +28 -0
  46. data/lib/vendor/dataflow/spec/future_queue_spec.rb +31 -0
  47. data/lib/vendor/dataflow/spec/inspect_spec.rb +19 -0
  48. data/lib/vendor/dataflow/spec/need_later_spec.rb +12 -0
  49. data/lib/vendor/dataflow/spec/port_spec.rb +26 -0
  50. data/lib/vendor/dataflow/spec/spec.opts +1 -0
  51. data/lib/vendor/dataflow/spec/spec_helper.rb +10 -0
  52. data/lib/vendor/escape/Readme +21 -0
  53. data/lib/vendor/escape/doc_include/template/qualitysmith.rb +631 -0
  54. data/lib/vendor/escape/lib/escape.rb +247 -0
  55. data/lib/vendor/json_pure/CHANGES +166 -0
  56. data/lib/vendor/json_pure/COPYING +58 -0
  57. data/lib/vendor/json_pure/GPL +340 -0
  58. data/lib/vendor/json_pure/README +358 -0
  59. data/lib/vendor/json_pure/Rakefile +292 -0
  60. data/lib/vendor/json_pure/TODO +1 -0
  61. data/lib/vendor/json_pure/VERSION +1 -0
  62. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkComparison.log +52 -0
  63. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast-autocorrelation.dat +1000 -0
  64. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast.dat +1001 -0
  65. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty-autocorrelation.dat +900 -0
  66. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty.dat +901 -0
  67. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe-autocorrelation.dat +1000 -0
  68. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe.dat +1001 -0
  69. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt.log +261 -0
  70. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast-autocorrelation.dat +1000 -0
  71. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast.dat +1001 -0
  72. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty-autocorrelation.dat +1000 -0
  73. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty.dat +1001 -0
  74. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe-autocorrelation.dat +1000 -0
  75. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe.dat +1001 -0
  76. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure.log +262 -0
  77. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator-autocorrelation.dat +1000 -0
  78. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator.dat +1001 -0
  79. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails.log +82 -0
  80. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkComparison.log +34 -0
  81. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser-autocorrelation.dat +900 -0
  82. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser.dat +901 -0
  83. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt.log +81 -0
  84. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser-autocorrelation.dat +1000 -0
  85. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser.dat +1001 -0
  86. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure.log +82 -0
  87. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser-autocorrelation.dat +1000 -0
  88. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser.dat +1001 -0
  89. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails.log +82 -0
  90. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser-autocorrelation.dat +1000 -0
  91. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser.dat +1001 -0
  92. data/lib/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML.log +82 -0
  93. data/lib/vendor/json_pure/benchmarks/generator2_benchmark.rb +222 -0
  94. data/lib/vendor/json_pure/benchmarks/generator_benchmark.rb +224 -0
  95. data/lib/vendor/json_pure/benchmarks/ohai.json +1216 -0
  96. data/lib/vendor/json_pure/benchmarks/ohai.ruby +1 -0
  97. data/lib/vendor/json_pure/benchmarks/parser2_benchmark.rb +251 -0
  98. data/lib/vendor/json_pure/benchmarks/parser_benchmark.rb +259 -0
  99. data/lib/vendor/json_pure/bin/edit_json.rb +9 -0
  100. data/lib/vendor/json_pure/bin/prettify_json.rb +75 -0
  101. data/lib/vendor/json_pure/data/example.json +1 -0
  102. data/lib/vendor/json_pure/data/index.html +38 -0
  103. data/lib/vendor/json_pure/data/prototype.js +4184 -0
  104. data/lib/vendor/json_pure/ext/json/ext/generator/extconf.rb +16 -0
  105. data/lib/vendor/json_pure/ext/json/ext/generator/generator.c +1323 -0
  106. data/lib/vendor/json_pure/ext/json/ext/generator/generator.h +170 -0
  107. data/lib/vendor/json_pure/ext/json/ext/parser/extconf.rb +15 -0
  108. data/lib/vendor/json_pure/ext/json/ext/parser/parser.c +1935 -0
  109. data/lib/vendor/json_pure/ext/json/ext/parser/parser.h +71 -0
  110. data/lib/vendor/json_pure/ext/json/ext/parser/parser.rl +792 -0
  111. data/lib/vendor/json_pure/install.rb +26 -0
  112. data/lib/vendor/json_pure/lib/json.rb +10 -0
  113. data/lib/vendor/json_pure/lib/json/Array.xpm +21 -0
  114. data/lib/vendor/json_pure/lib/json/FalseClass.xpm +21 -0
  115. data/lib/vendor/json_pure/lib/json/Hash.xpm +21 -0
  116. data/lib/vendor/json_pure/lib/json/Key.xpm +73 -0
  117. data/lib/vendor/json_pure/lib/json/NilClass.xpm +21 -0
  118. data/lib/vendor/json_pure/lib/json/Numeric.xpm +28 -0
  119. data/lib/vendor/json_pure/lib/json/String.xpm +96 -0
  120. data/lib/vendor/json_pure/lib/json/TrueClass.xpm +21 -0
  121. data/lib/vendor/json_pure/lib/json/add/core.rb +148 -0
  122. data/lib/vendor/json_pure/lib/json/add/rails.rb +58 -0
  123. data/lib/vendor/json_pure/lib/json/common.rb +397 -0
  124. data/lib/vendor/json_pure/lib/json/editor.rb +1371 -0
  125. data/lib/vendor/json_pure/lib/json/ext.rb +15 -0
  126. data/lib/vendor/json_pure/lib/json/json.xpm +1499 -0
  127. data/lib/vendor/json_pure/lib/json/pure.rb +77 -0
  128. data/lib/vendor/json_pure/lib/json/pure/generator.rb +452 -0
  129. data/lib/vendor/json_pure/lib/json/pure/parser.rb +307 -0
  130. data/lib/vendor/json_pure/lib/json/version.rb +8 -0
  131. data/lib/vendor/json_pure/tests/fixtures/fail1.json +1 -0
  132. data/lib/vendor/json_pure/tests/fixtures/fail10.json +1 -0
  133. data/lib/vendor/json_pure/tests/fixtures/fail11.json +1 -0
  134. data/lib/vendor/json_pure/tests/fixtures/fail12.json +1 -0
  135. data/lib/vendor/json_pure/tests/fixtures/fail13.json +1 -0
  136. data/lib/vendor/json_pure/tests/fixtures/fail14.json +1 -0
  137. data/lib/vendor/json_pure/tests/fixtures/fail18.json +1 -0
  138. data/lib/vendor/json_pure/tests/fixtures/fail19.json +1 -0
  139. data/lib/vendor/json_pure/tests/fixtures/fail2.json +1 -0
  140. data/lib/vendor/json_pure/tests/fixtures/fail20.json +1 -0
  141. data/lib/vendor/json_pure/tests/fixtures/fail21.json +1 -0
  142. data/lib/vendor/json_pure/tests/fixtures/fail22.json +1 -0
  143. data/lib/vendor/json_pure/tests/fixtures/fail23.json +1 -0
  144. data/lib/vendor/json_pure/tests/fixtures/fail24.json +1 -0
  145. data/lib/vendor/json_pure/tests/fixtures/fail25.json +1 -0
  146. data/lib/vendor/json_pure/tests/fixtures/fail27.json +2 -0
  147. data/lib/vendor/json_pure/tests/fixtures/fail28.json +2 -0
  148. data/lib/vendor/json_pure/tests/fixtures/fail3.json +1 -0
  149. data/lib/vendor/json_pure/tests/fixtures/fail4.json +1 -0
  150. data/lib/vendor/json_pure/tests/fixtures/fail5.json +1 -0
  151. data/lib/vendor/json_pure/tests/fixtures/fail6.json +1 -0
  152. data/lib/vendor/json_pure/tests/fixtures/fail7.json +1 -0
  153. data/lib/vendor/json_pure/tests/fixtures/fail8.json +1 -0
  154. data/lib/vendor/json_pure/tests/fixtures/fail9.json +1 -0
  155. data/lib/vendor/json_pure/tests/fixtures/pass1.json +56 -0
  156. data/lib/vendor/json_pure/tests/fixtures/pass15.json +1 -0
  157. data/lib/vendor/json_pure/tests/fixtures/pass16.json +1 -0
  158. data/lib/vendor/json_pure/tests/fixtures/pass17.json +1 -0
  159. data/lib/vendor/json_pure/tests/fixtures/pass2.json +1 -0
  160. data/lib/vendor/json_pure/tests/fixtures/pass26.json +1 -0
  161. data/lib/vendor/json_pure/tests/fixtures/pass3.json +6 -0
  162. data/lib/vendor/json_pure/tests/test_json.rb +361 -0
  163. data/lib/vendor/json_pure/tests/test_json_addition.rb +162 -0
  164. data/lib/vendor/json_pure/tests/test_json_encoding.rb +68 -0
  165. data/lib/vendor/json_pure/tests/test_json_fixtures.rb +34 -0
  166. data/lib/vendor/json_pure/tests/test_json_generate.rb +122 -0
  167. data/lib/vendor/json_pure/tests/test_json_rails.rb +144 -0
  168. data/lib/vendor/json_pure/tests/test_json_unicode.rb +76 -0
  169. data/lib/vendor/json_pure/tools/fuzz.rb +139 -0
  170. data/lib/vendor/json_pure/tools/server.rb +61 -0
  171. data/lib/vendor/open4/lib/open4.rb +403 -0
  172. data/lib/vendor/thor/CHANGELOG.rdoc +89 -0
  173. data/lib/vendor/thor/LICENSE +20 -0
  174. data/lib/vendor/thor/README.rdoc +297 -0
  175. data/lib/vendor/thor/Thorfile +69 -0
  176. data/lib/vendor/thor/bin/rake2thor +86 -0
  177. data/lib/vendor/thor/bin/thor +6 -0
  178. data/lib/vendor/thor/lib/thor.rb +244 -0
  179. data/lib/vendor/thor/lib/thor/actions.rb +275 -0
  180. data/lib/vendor/thor/lib/thor/actions/create_file.rb +103 -0
  181. data/lib/vendor/thor/lib/thor/actions/directory.rb +91 -0
  182. data/lib/vendor/thor/lib/thor/actions/empty_directory.rb +134 -0
  183. data/lib/vendor/thor/lib/thor/actions/file_manipulation.rb +223 -0
  184. data/lib/vendor/thor/lib/thor/actions/inject_into_file.rb +104 -0
  185. data/lib/vendor/thor/lib/thor/base.rb +540 -0
  186. data/lib/vendor/thor/lib/thor/core_ext/file_binary_read.rb +9 -0
  187. data/lib/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +75 -0
  188. data/lib/vendor/thor/lib/thor/core_ext/ordered_hash.rb +100 -0
  189. data/lib/vendor/thor/lib/thor/error.rb +30 -0
  190. data/lib/vendor/thor/lib/thor/group.rb +271 -0
  191. data/lib/vendor/thor/lib/thor/invocation.rb +180 -0
  192. data/lib/vendor/thor/lib/thor/parser.rb +4 -0
  193. data/lib/vendor/thor/lib/thor/parser/argument.rb +67 -0
  194. data/lib/vendor/thor/lib/thor/parser/arguments.rb +150 -0
  195. data/lib/vendor/thor/lib/thor/parser/option.rb +128 -0
  196. data/lib/vendor/thor/lib/thor/parser/options.rb +169 -0
  197. data/lib/vendor/thor/lib/thor/rake_compat.rb +66 -0
  198. data/lib/vendor/thor/lib/thor/runner.rb +314 -0
  199. data/lib/vendor/thor/lib/thor/shell.rb +83 -0
  200. data/lib/vendor/thor/lib/thor/shell/basic.rb +239 -0
  201. data/lib/vendor/thor/lib/thor/shell/color.rb +108 -0
  202. data/lib/vendor/thor/lib/thor/task.rb +102 -0
  203. data/lib/vendor/thor/lib/thor/util.rb +230 -0
  204. data/lib/vendor/thor/lib/thor/version.rb +3 -0
  205. data/lib/vendor/thor/thor.gemspec +120 -0
  206. data/spec/custom_deploy_spec.rb +95 -0
  207. data/spec/deploy_hook_spec.rb +211 -0
  208. data/spec/fixtures/gitrepo.tar.gz +0 -0
  209. data/spec/fixtures/gitrepo/foo +0 -0
  210. data/spec/fixtures/invalid_hook.rb +1 -0
  211. data/spec/fixtures/valid_hook.rb +1 -0
  212. data/spec/git_strategy_spec.rb +22 -0
  213. data/spec/lockfile_parser_spec.rb +30 -0
  214. data/spec/spec_helper.rb +37 -0
  215. data/spec/support/lockfiles/0.9-no-bundler +111 -0
  216. data/spec/support/lockfiles/0.9-with-bundler +117 -0
  217. data/spec/support/lockfiles/1.0-no-bundler +54 -0
  218. data/spec/support/lockfiles/1.0.0.rc.1-with-bundler +162 -0
  219. data/spec/support/lockfiles/not-a-lockfile +10 -0
  220. metadata +279 -0
@@ -0,0 +1,139 @@
1
+ require 'json'
2
+
3
+ require 'iconv'
4
+ ISO_8859_1_TO_UTF8 = Iconv.new('utf-8', 'iso-8859-15')
5
+ class ::String
6
+ def to_utf8
7
+ ISO_8859_1_TO_UTF8.iconv self
8
+ end
9
+ end
10
+
11
+ class Fuzzer
12
+ def initialize(n, freqs = {})
13
+ sum = freqs.inject(0.0) { |s, x| s + x.last }
14
+ freqs.each_key { |x| freqs[x] /= sum }
15
+ s = 0.0
16
+ freqs.each_key do |x|
17
+ freqs[x] = s .. (s + t = freqs[x])
18
+ s += t
19
+ end
20
+ @freqs = freqs
21
+ @n = n
22
+ @alpha = (0..0xff).to_a
23
+ end
24
+
25
+ def random_string
26
+ s = ''
27
+ 30.times { s << @alpha[rand(@alpha.size)] }
28
+ s.to_utf8
29
+ end
30
+
31
+ def pick
32
+ r = rand
33
+ found = @freqs.find { |k, f| f.include? rand }
34
+ found && found.first
35
+ end
36
+
37
+ def make_pick
38
+ k = pick
39
+ case
40
+ when k == Hash, k == Array
41
+ k.new
42
+ when k == true, k == false, k == nil
43
+ k
44
+ when k == String
45
+ random_string
46
+ when k == Fixnum
47
+ rand(2 ** 30) - 2 ** 29
48
+ when k == Bignum
49
+ rand(2 ** 70) - 2 ** 69
50
+ end
51
+ end
52
+
53
+ def fuzz(current = nil)
54
+ if @n > 0
55
+ case current
56
+ when nil
57
+ @n -= 1
58
+ current = fuzz [ Hash, Array ][rand(2)].new
59
+ when Array
60
+ while @n > 0
61
+ @n -= 1
62
+ current << case p = make_pick
63
+ when Array, Hash
64
+ fuzz(p)
65
+ else
66
+ p
67
+ end
68
+ end
69
+ when Hash
70
+ while @n > 0
71
+ @n -= 1
72
+ current[random_string] = case p = make_pick
73
+ when Array, Hash
74
+ fuzz(p)
75
+ else
76
+ p
77
+ end
78
+ end
79
+ end
80
+ end
81
+ current
82
+ end
83
+ end
84
+
85
+ class MyState < JSON.state
86
+ WS = " \r\t\n"
87
+
88
+ def initialize
89
+ super(
90
+ :indent => make_spaces,
91
+ :space => make_spaces,
92
+ :space_before => make_spaces,
93
+ :object_nl => make_spaces,
94
+ :array_nl => make_spaces,
95
+ :max_nesting => false
96
+ )
97
+ end
98
+
99
+ def make_spaces
100
+ s = ''
101
+ rand(1).times { s << WS[rand(WS.size)] }
102
+ s
103
+ end
104
+ end
105
+
106
+ n = (ARGV.shift || 500).to_i
107
+ loop do
108
+ fuzzer = Fuzzer.new(n,
109
+ Hash => 25,
110
+ Array => 25,
111
+ String => 10,
112
+ Fixnum => 10,
113
+ Bignum => 10,
114
+ nil => 5,
115
+ true => 5,
116
+ false => 5
117
+ )
118
+ o1 = fuzzer.fuzz
119
+ json = JSON.generate o1, MyState.new
120
+ if $DEBUG
121
+ puts "-" * 80
122
+ puts json, json.size
123
+ else
124
+ puts json.size
125
+ end
126
+ begin
127
+ o2 = JSON.parse(json, :max_nesting => false)
128
+ rescue JSON::ParserError => e
129
+ puts "Caught #{e.class}: #{e.message}\n#{e.backtrace * "\n"}"
130
+ puts "o1 = #{o1.inspect}", "json = #{json}", "json_str = #{json.inspect}"
131
+ puts "locals = #{local_variables.inspect}"
132
+ exit
133
+ end
134
+ if o1 != o2
135
+ puts "mismatch", "o1 = #{o1.inspect}", "o2 = #{o2.inspect}",
136
+ "json = #{json}", "json_str = #{json.inspect}"
137
+ puts "locals = #{local_variables.inspect}"
138
+ end
139
+ end
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'webrick'
4
+ include WEBrick
5
+ $:.unshift 'ext'
6
+ $:.unshift 'lib'
7
+ require 'json'
8
+
9
+ class JSONServlet < HTTPServlet::AbstractServlet
10
+ @@count = 1
11
+
12
+ def do_GET(req, res)
13
+ obj = {
14
+ "TIME" => Time.now.strftime("%FT%T"),
15
+ "foo" => "Bär",
16
+ "bar" => "© ≠ €!",
17
+ 'a' => 2,
18
+ 'b' => 3.141,
19
+ 'COUNT' => @@count += 1,
20
+ 'c' => 'c',
21
+ 'd' => [ 1, "b", 3.14 ],
22
+ 'e' => { 'foo' => 'bar' },
23
+ 'g' => "松本行弘",
24
+ 'h' => 1000.0,
25
+ 'i' => 0.001,
26
+ 'j' => "\xf0\xa0\x80\x81",
27
+ }
28
+ res.body = JSON.generate obj
29
+ res['Content-Type'] = "application/json"
30
+ end
31
+ end
32
+
33
+ def create_server(err, dir, port)
34
+ dir = File.expand_path(dir)
35
+ err.puts "Surf to:", "http://#{Socket.gethostname}:#{port}"
36
+
37
+ s = HTTPServer.new(
38
+ :Port => port,
39
+ :DocumentRoot => dir,
40
+ :Logger => WEBrick::Log.new(err),
41
+ :AccessLog => [
42
+ [ err, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
43
+ [ err, WEBrick::AccessLog::REFERER_LOG_FORMAT ],
44
+ [ err, WEBrick::AccessLog::AGENT_LOG_FORMAT ]
45
+ ]
46
+ )
47
+ s.mount("/json", JSONServlet)
48
+ s
49
+ end
50
+
51
+ default_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'data'))
52
+ dir = ARGV.shift || default_dir
53
+ port = (ARGV.shift || 6666).to_i
54
+ s = create_server(STDERR, dir, 6666)
55
+ t = Thread.new { s.start }
56
+ trap(:INT) do
57
+ s.shutdown
58
+ t.join
59
+ exit
60
+ end
61
+ sleep
@@ -0,0 +1,403 @@
1
+ # vim: ts=2:sw=2:sts=2:et:fdm=marker
2
+ require 'fcntl'
3
+ require 'timeout'
4
+ require 'thread'
5
+
6
+ module Open4
7
+ #--{{{
8
+ VERSION = '1.1.0'
9
+ def self.version() VERSION end
10
+
11
+ class Error < ::StandardError; end
12
+
13
+ def popen4(*cmd, &b)
14
+ #--{{{
15
+ pw, pr, pe, ps = IO.pipe, IO.pipe, IO.pipe, IO.pipe
16
+
17
+ verbose = $VERBOSE
18
+ begin
19
+ $VERBOSE = nil
20
+ ps.first.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
21
+ ps.last.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
22
+
23
+ cid = fork {
24
+ pw.last.close
25
+ STDIN.reopen pw.first
26
+ pw.first.close
27
+
28
+ pr.first.close
29
+ STDOUT.reopen pr.last
30
+ pr.last.close
31
+
32
+ pe.first.close
33
+ STDERR.reopen pe.last
34
+ pe.last.close
35
+
36
+ STDOUT.sync = STDERR.sync = true
37
+
38
+ begin
39
+ exec(*cmd)
40
+ raise 'forty-two'
41
+ rescue Exception => e
42
+ Marshal.dump(e, ps.last)
43
+ ps.last.flush
44
+ end
45
+ ps.last.close unless (ps.last.closed?)
46
+ exit!
47
+ }
48
+ ensure
49
+ $VERBOSE = verbose
50
+ end
51
+
52
+ [pw.first, pr.last, pe.last, ps.last].each{|fd| fd.close}
53
+
54
+ begin
55
+ e = Marshal.load ps.first
56
+ raise(Exception === e ? e : "unknown failure!")
57
+ rescue EOFError # If we get an EOF error, then the exec was successful
58
+ 42
59
+ ensure
60
+ ps.first.close
61
+ end
62
+
63
+ pw.last.sync = true
64
+
65
+ pi = [pw.last, pr.first, pe.first]
66
+
67
+ if b
68
+ begin
69
+ b[cid, *pi]
70
+ Process.waitpid2(cid).last
71
+ ensure
72
+ pi.each{|fd| fd.close unless fd.closed?}
73
+ end
74
+ else
75
+ [cid, pw.last, pr.first, pe.first]
76
+ end
77
+ #--}}}
78
+ end
79
+ alias open4 popen4
80
+ module_function :popen4
81
+ module_function :open4
82
+
83
+ class SpawnError < Error
84
+ #--{{{
85
+ attr 'cmd'
86
+ attr 'status'
87
+ attr 'signals'
88
+ def exitstatus
89
+ @status.exitstatus
90
+ end
91
+ def initialize cmd, status
92
+ @cmd, @status = cmd, status
93
+ @signals = {}
94
+ if status.signaled?
95
+ @signals['termsig'] = status.termsig
96
+ @signals['stopsig'] = status.stopsig
97
+ end
98
+ sigs = @signals.map{|k,v| "#{ k }:#{ v.inspect }"}.join(' ')
99
+ super "cmd <#{ cmd }> failed with status <#{ exitstatus.inspect }> signals <#{ sigs }>"
100
+ end
101
+ #--}}}
102
+ end
103
+
104
+ class ThreadEnsemble
105
+ #--{{{
106
+ attr 'threads'
107
+
108
+ def initialize cid
109
+ @cid, @threads, @argv, @done, @running = cid, [], [], Queue.new, false
110
+ @killed = false
111
+ end
112
+
113
+ def add_thread *a, &b
114
+ @running ? raise : (@argv << [a, b])
115
+ end
116
+
117
+ #
118
+ # take down process more nicely
119
+ #
120
+ def killall
121
+ c = Thread.critical
122
+ return nil if @killed
123
+ Thread.critical = true
124
+ (@threads - [Thread.current]).each{|t| t.kill rescue nil}
125
+ @killed = true
126
+ ensure
127
+ Thread.critical = c
128
+ end
129
+
130
+ def run
131
+ @running = true
132
+
133
+ begin
134
+ @argv.each do |a, b|
135
+ @threads << Thread.new(*a) do |*a|
136
+ begin
137
+ b[*a]
138
+ ensure
139
+ killall rescue nil if $!
140
+ @done.push Thread.current
141
+ end
142
+ end
143
+ end
144
+ rescue
145
+ killall
146
+ raise
147
+ ensure
148
+ all_done
149
+ end
150
+
151
+ @threads.map{|t| t.value}
152
+ end
153
+
154
+ def all_done
155
+ @threads.size.times{ @done.pop }
156
+ end
157
+ #--}}}
158
+ end
159
+
160
+ def to timeout = nil
161
+ #--{{{
162
+ Timeout.timeout(timeout){ yield }
163
+ #--}}}
164
+ end
165
+ module_function :to
166
+
167
+ def new_thread *a, &b
168
+ #--{{{
169
+ cur = Thread.current
170
+ Thread.new(*a) do |*a|
171
+ begin
172
+ b[*a]
173
+ rescue Exception => e
174
+ cur.raise e
175
+ end
176
+ end
177
+ #--}}}
178
+ end
179
+ module_function :new_thread
180
+
181
+ def getopts opts = {}
182
+ #--{{{
183
+ lambda do |*args|
184
+ keys, default, ignored = args
185
+ catch('opt') do
186
+ [keys].flatten.each do |key|
187
+ [key, key.to_s, key.to_s.intern].each do |key|
188
+ throw 'opt', opts[key] if opts.has_key?(key)
189
+ end
190
+ end
191
+ default
192
+ end
193
+ end
194
+ #--}}}
195
+ end
196
+ module_function :getopts
197
+
198
+ def relay src, dst = nil, t = nil
199
+ #--{{{
200
+ send_dst =
201
+ if dst.respond_to?(:call)
202
+ lambda{|buf| dst.call(buf)}
203
+ elsif dst.respond_to?(:<<)
204
+ lambda{|buf| dst << buf }
205
+ else
206
+ lambda{|buf| buf }
207
+ end
208
+
209
+ unless src.nil?
210
+ if src.respond_to? :gets
211
+ while buf = to(t){ src.gets }
212
+ send_dst[buf]
213
+ end
214
+
215
+ elsif src.respond_to? :each
216
+ q = Queue.new
217
+ th = nil
218
+
219
+ timer_set = lambda do |t|
220
+ th = new_thread{ to(t){ q.pop } }
221
+ end
222
+
223
+ timer_cancel = lambda do |t|
224
+ th.kill if th rescue nil
225
+ end
226
+
227
+ timer_set[t]
228
+ begin
229
+ src.each do |buf|
230
+ timer_cancel[t]
231
+ send_dst[buf]
232
+ timer_set[t]
233
+ end
234
+ ensure
235
+ timer_cancel[t]
236
+ end
237
+
238
+ elsif src.respond_to? :read
239
+ buf = to(t){ src.read }
240
+ send_dst[buf]
241
+
242
+ else
243
+ buf = to(t){ src.to_s }
244
+ send_dst[buf]
245
+ end
246
+ end
247
+ #--}}}
248
+ end
249
+ module_function :relay
250
+
251
+ def spawn arg, *argv
252
+ #--{{{
253
+ argv.unshift(arg)
254
+ opts = ((argv.size > 1 and Hash === argv.last) ? argv.pop : {})
255
+ argv.flatten!
256
+ cmd = argv.join(' ')
257
+
258
+
259
+ getopt = getopts opts
260
+
261
+ ignore_exit_failure = getopt[ 'ignore_exit_failure', getopt['quiet', false] ]
262
+ ignore_exec_failure = getopt[ 'ignore_exec_failure', !getopt['raise', true] ]
263
+ exitstatus = getopt[ %w( exitstatus exit_status status ) ]
264
+ stdin = getopt[ %w( stdin in i 0 ) << 0 ]
265
+ stdout = getopt[ %w( stdout out o 1 ) << 1 ]
266
+ stderr = getopt[ %w( stderr err e 2 ) << 2 ]
267
+ pid = getopt[ 'pid' ]
268
+ timeout = getopt[ %w( timeout spawn_timeout ) ]
269
+ stdin_timeout = getopt[ %w( stdin_timeout ) ]
270
+ stdout_timeout = getopt[ %w( stdout_timeout io_timeout ) ]
271
+ stderr_timeout = getopt[ %w( stderr_timeout ) ]
272
+ status = getopt[ %w( status ) ]
273
+ cwd = getopt[ %w( cwd dir ) ]
274
+
275
+ exitstatus =
276
+ case exitstatus
277
+ when TrueClass, FalseClass
278
+ ignore_exit_failure = true if exitstatus
279
+ [0]
280
+ else
281
+ [*(exitstatus || 0)].map{|i| Integer i}
282
+ end
283
+
284
+ stdin ||= '' if stdin_timeout
285
+ stdout ||= '' if stdout_timeout
286
+ stderr ||= '' if stderr_timeout
287
+
288
+ started = false
289
+
290
+ status =
291
+ begin
292
+ chdir(cwd) do
293
+ Timeout::timeout(timeout) do
294
+ popen4(*argv) do |c, i, o, e|
295
+ started = true
296
+
297
+ %w( replace pid= << push update ).each do |msg|
298
+ break(pid.send(msg, c)) if pid.respond_to? msg
299
+ end
300
+
301
+ te = ThreadEnsemble.new c
302
+
303
+ te.add_thread(i, stdin) do |i, stdin|
304
+ relay stdin, i, stdin_timeout
305
+ i.close rescue nil
306
+ end
307
+
308
+ te.add_thread(o, stdout) do |o, stdout|
309
+ relay o, stdout, stdout_timeout
310
+ end
311
+
312
+ te.add_thread(e, stderr) do |o, stderr|
313
+ relay e, stderr, stderr_timeout
314
+ end
315
+
316
+ te.run
317
+ end
318
+ end
319
+ end
320
+ rescue
321
+ raise unless(not started and ignore_exec_failure)
322
+ end
323
+
324
+ raise SpawnError.new(cmd, status) unless
325
+ (ignore_exit_failure or (status.nil? and ignore_exec_failure) or exitstatus.include?(status.exitstatus))
326
+
327
+ status
328
+ #--}}}
329
+ end
330
+ module_function :spawn
331
+
332
+ def chdir cwd, &block
333
+ return(block.call Dir.pwd) unless cwd
334
+ Dir.chdir cwd, &block
335
+ end
336
+ module_function :chdir
337
+
338
+ def background arg, *argv
339
+ #--{{{
340
+ require 'thread'
341
+ q = Queue.new
342
+ opts = { 'pid' => q, :pid => q }
343
+ case argv.last
344
+ when Hash
345
+ argv.last.update opts
346
+ else
347
+ argv.push opts
348
+ end
349
+ thread = Thread.new(arg, argv){|arg, argv| spawn arg, *argv}
350
+ sc = class << thread; self; end
351
+ sc.module_eval {
352
+ define_method(:pid){ @pid ||= q.pop }
353
+ define_method(:spawn_status){ @spawn_status ||= value }
354
+ define_method(:exitstatus){ @exitstatus ||= spawn_status.exitstatus }
355
+ }
356
+ thread
357
+ #--}}}
358
+ end
359
+ alias bg background
360
+ module_function :background
361
+ module_function :bg
362
+
363
+ def maim pid, opts = {}
364
+ #--{{{
365
+ getopt = getopts opts
366
+ sigs = getopt[ 'signals', %w(SIGTERM SIGQUIT SIGKILL) ]
367
+ suspend = getopt[ 'suspend', 4 ]
368
+ pid = Integer pid
369
+ existed = false
370
+ sigs.each do |sig|
371
+ begin
372
+ Process.kill sig, pid
373
+ existed = true
374
+ rescue Errno::ESRCH
375
+ return(existed ? nil : true)
376
+ end
377
+ return true unless alive? pid
378
+ sleep suspend
379
+ return true unless alive? pid
380
+ end
381
+ return(not alive?(pid))
382
+ #--}}}
383
+ end
384
+ module_function :maim
385
+
386
+ def alive pid
387
+ #--{{{
388
+ pid = Integer pid
389
+ begin
390
+ Process.kill 0, pid
391
+ true
392
+ rescue Errno::ESRCH
393
+ false
394
+ end
395
+ #--}}}
396
+ end
397
+ alias alive? alive
398
+ module_function :alive
399
+ module_function :'alive?'
400
+ #--}}}
401
+ end
402
+
403
+ def open4(*cmd, &b) cmd.size == 0 ? Open4 : Open4::popen4(*cmd, &b) end