auser-poolparty 0.2.66 → 0.2.67

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 (159) hide show
  1. data/Manifest.txt +83 -41
  2. data/PostInstall.txt +2 -2
  3. data/README.txt +1 -2
  4. data/Rakefile +14 -1
  5. data/bin/cloud-start +11 -10
  6. data/bin/{pool-spec → pool-generate} +0 -0
  7. data/bin/pool-init +3 -3
  8. data/bin/pool-start +8 -7
  9. data/bin/server-update-hosts +1 -1
  10. data/lib/erlang/messenger/ebin/pm_client_rel-0.1.rel +1 -1
  11. data/lib/erlang/messenger/ebin/pm_master_rel-0.1.rel +1 -1
  12. data/lib/erlang/messenger/ebin/pm_node_rel-0.1.rel +1 -1
  13. data/lib/erlang/messenger/include/defines.hrl +7 -3
  14. data/lib/erlang/messenger/lib/eunit/.svn/all-wcprops +53 -0
  15. data/lib/erlang/messenger/lib/eunit/.svn/entries +140 -0
  16. data/lib/erlang/messenger/lib/eunit/.svn/format +1 -0
  17. data/lib/erlang/messenger/lib/eunit/.svn/prop-base/NOTES.svn-base +5 -0
  18. data/lib/erlang/messenger/lib/eunit/.svn/text-base/AUTHORS.svn-base +2 -0
  19. data/lib/erlang/messenger/lib/eunit/.svn/text-base/CHANGELOG.svn-base +14 -0
  20. data/lib/erlang/messenger/lib/eunit/.svn/text-base/COPYING.svn-base +504 -0
  21. data/lib/erlang/messenger/lib/eunit/.svn/text-base/NOTES.svn-base +276 -0
  22. data/lib/erlang/messenger/lib/eunit/.svn/text-base/README.svn-base +3 -0
  23. data/lib/erlang/messenger/lib/eunit/.svn/text-base/sys.config.svn-base +9 -0
  24. data/lib/erlang/messenger/lib/eunit/.svn/text-base/vsn.mk.svn-base +1 -0
  25. data/lib/erlang/messenger/lib/eunit/doc/.svn/all-wcprops +59 -0
  26. data/lib/erlang/messenger/lib/eunit/doc/.svn/entries +142 -0
  27. data/lib/erlang/messenger/lib/eunit/doc/.svn/format +1 -0
  28. data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/erlang.png.svn-base +5 -0
  29. data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/eunit.html.svn-base +5 -0
  30. data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/index.html.svn-base +5 -0
  31. data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/modules-frame.html.svn-base +5 -0
  32. data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/overview-summary.html.svn-base +5 -0
  33. data/lib/erlang/messenger/lib/eunit/doc/.svn/prop-base/packages-frame.html.svn-base +5 -0
  34. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/edoc-info.svn-base +3 -0
  35. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/erlang.png.svn-base +0 -0
  36. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/eunit.html.svn-base +172 -0
  37. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/index.html.svn-base +17 -0
  38. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/modules-frame.html.svn-base +12 -0
  39. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/overview-summary.html.svn-base +984 -0
  40. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/overview.edoc.svn-base +980 -0
  41. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/packages-frame.html.svn-base +11 -0
  42. data/lib/erlang/messenger/lib/eunit/doc/.svn/text-base/stylesheet.css.svn-base +55 -0
  43. data/lib/erlang/messenger/lib/eunit/ebin/.svn/all-wcprops +5 -0
  44. data/lib/erlang/messenger/lib/eunit/ebin/.svn/dir-prop-base +8 -0
  45. data/lib/erlang/messenger/lib/eunit/ebin/.svn/entries +28 -0
  46. data/lib/erlang/messenger/lib/eunit/ebin/.svn/format +1 -0
  47. data/lib/erlang/messenger/lib/eunit/examples/.svn/all-wcprops +23 -0
  48. data/lib/erlang/messenger/lib/eunit/examples/.svn/entries +66 -0
  49. data/lib/erlang/messenger/lib/eunit/examples/.svn/format +1 -0
  50. data/lib/erlang/messenger/lib/eunit/examples/.svn/prop-base/eunit_examples.erl.svn-base +5 -0
  51. data/lib/erlang/messenger/lib/eunit/examples/.svn/prop-base/fib.erl.svn-base +5 -0
  52. data/lib/erlang/messenger/lib/eunit/examples/.svn/text-base/eunit_examples.erl.svn-base +339 -0
  53. data/lib/erlang/messenger/lib/eunit/examples/.svn/text-base/fib.erl.svn-base +19 -0
  54. data/lib/erlang/messenger/lib/eunit/examples/.svn/text-base/tests.txt.svn-base +1 -0
  55. data/lib/erlang/messenger/lib/eunit/include/.svn/all-wcprops +11 -0
  56. data/lib/erlang/messenger/lib/eunit/include/.svn/entries +41 -0
  57. data/lib/erlang/messenger/lib/eunit/include/.svn/format +1 -0
  58. data/lib/erlang/messenger/lib/eunit/include/.svn/prop-base/eunit.hrl.svn-base +5 -0
  59. data/lib/erlang/messenger/lib/eunit/include/.svn/text-base/eunit.hrl.svn-base +313 -0
  60. data/lib/erlang/messenger/lib/eunit/src/.svn/all-wcprops +113 -0
  61. data/lib/erlang/messenger/lib/eunit/src/.svn/entries +259 -0
  62. data/lib/erlang/messenger/lib/eunit/src/.svn/format +1 -0
  63. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/autoload.erl.svn-base +5 -0
  64. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/code_monitor.erl.svn-base +5 -0
  65. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit.erl.svn-base +5 -0
  66. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_autoexport.erl.svn-base +5 -0
  67. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_data.erl.svn-base +5 -0
  68. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_internal.hrl.svn-base +5 -0
  69. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_lib.erl.svn-base +5 -0
  70. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_proc.erl.svn-base +5 -0
  71. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_serial.erl.svn-base +5 -0
  72. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_server.erl.svn-base +5 -0
  73. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_striptests.erl.svn-base +5 -0
  74. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_test.erl.svn-base +5 -0
  75. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_tests.erl.svn-base +5 -0
  76. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/eunit_tty.erl.svn-base +5 -0
  77. data/lib/erlang/messenger/lib/eunit/src/.svn/prop-base/file_monitor.erl.svn-base +5 -0
  78. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/autoload.erl.svn-base +388 -0
  79. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/code_monitor.erl.svn-base +243 -0
  80. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit.app.src.svn-base +21 -0
  81. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit.appup.src.svn-base +1 -0
  82. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit.erl.svn-base +196 -0
  83. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_autoexport.erl.svn-base +102 -0
  84. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_data.erl.svn-base +798 -0
  85. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_internal.hrl.svn-base +48 -0
  86. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_lib.erl.svn-base +682 -0
  87. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_proc.erl.svn-base +552 -0
  88. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_serial.erl.svn-base +157 -0
  89. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_server.erl.svn-base +340 -0
  90. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_striptests.erl.svn-base +64 -0
  91. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_test.erl.svn-base +334 -0
  92. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_tests.erl.svn-base +45 -0
  93. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/eunit_tty.erl.svn-base +272 -0
  94. data/lib/erlang/messenger/lib/eunit/src/.svn/text-base/file_monitor.erl.svn-base +409 -0
  95. data/lib/erlang/messenger/pm_client_rel-0.1.boot +0 -0
  96. data/lib/erlang/messenger/pm_client_rel-0.1.script +77 -85
  97. data/lib/erlang/messenger/pm_master_rel-0.1.boot +0 -0
  98. data/lib/erlang/messenger/pm_master_rel-0.1.script +78 -85
  99. data/lib/erlang/messenger/pm_node_rel-0.1.boot +0 -0
  100. data/lib/erlang/messenger/pm_node_rel-0.1.script +77 -86
  101. data/lib/erlang/messenger/src/pm_node.erl +46 -9
  102. data/lib/erlang/messenger/src/utils.erl +7 -1
  103. data/lib/poolparty.rb +17 -23
  104. data/lib/poolparty/base_packages/poolparty.rb +1 -1
  105. data/lib/poolparty/core/string.rb +11 -2
  106. data/lib/poolparty/helpers/binary.rb +31 -0
  107. data/lib/poolparty/helpers/console.rb +25 -16
  108. data/lib/poolparty/helpers/nice_printer.rb +36 -0
  109. data/lib/poolparty/helpers/optioner.rb +8 -0
  110. data/lib/poolparty/helpers/provisioner_base.rb +7 -5
  111. data/lib/poolparty/helpers/provisioners/master.rb +1 -1
  112. data/lib/poolparty/helpers/provisioners/slave.rb +2 -1
  113. data/lib/poolparty/modules/cloud_resourcer.rb +1 -1
  114. data/lib/poolparty/modules/file_writer.rb +12 -1
  115. data/lib/poolparty/modules/resourcing_dsl.rb +2 -1
  116. data/lib/poolparty/monitors/base_monitor.rb +3 -0
  117. data/lib/poolparty/net/remoter.rb +13 -11
  118. data/lib/poolparty/pool/base.rb +25 -13
  119. data/lib/poolparty/pool/cloud.rb +32 -10
  120. data/lib/poolparty/pool/custom_resource.rb +16 -7
  121. data/lib/poolparty/pool/plugin_model.rb +2 -2
  122. data/lib/poolparty/pool/pool.rb +2 -2
  123. data/lib/poolparty/pool/resource.rb +25 -7
  124. data/lib/poolparty/pool/resources/class_package.rb +3 -2
  125. data/lib/poolparty/pool/resources/exec.rb +1 -1
  126. data/lib/poolparty/pool/resources/variable.rb +4 -0
  127. data/lib/poolparty/version.rb +1 -1
  128. data/poolparty.gemspec +13 -11
  129. data/spec/poolparty/core/hash_spec.rb +1 -1
  130. data/spec/poolparty/core/time_spec.rb +1 -1
  131. data/spec/poolparty/net/remote_spec.rb +1 -1
  132. data/spec/poolparty/pool/base_spec.rb +25 -20
  133. data/spec/poolparty/pool/cloud_spec.rb +50 -3
  134. data/spec/poolparty/pool/plugin_spec.rb +1 -0
  135. data/spec/poolparty/pool/resource_spec.rb +4 -3
  136. data/spec/poolparty/spec_helper.rb +3 -4
  137. data/tasks/deployment.rake +15 -3
  138. data/website/index.html +2 -2
  139. metadata +88 -46
  140. data/lib/erlang/messenger/Makefile +0 -15
  141. data/lib/erlang/messenger/lib/eunit/Makefile +0 -28
  142. data/lib/erlang/messenger/lib/eunit/ebin/autoload.beam +0 -0
  143. data/lib/erlang/messenger/lib/eunit/ebin/code_monitor.beam +0 -0
  144. data/lib/erlang/messenger/lib/eunit/ebin/eunit.beam +0 -0
  145. data/lib/erlang/messenger/lib/eunit/ebin/eunit_autoexport.beam +0 -0
  146. data/lib/erlang/messenger/lib/eunit/ebin/eunit_data.beam +0 -0
  147. data/lib/erlang/messenger/lib/eunit/ebin/eunit_lib.beam +0 -0
  148. data/lib/erlang/messenger/lib/eunit/ebin/eunit_proc.beam +0 -0
  149. data/lib/erlang/messenger/lib/eunit/ebin/eunit_serial.beam +0 -0
  150. data/lib/erlang/messenger/lib/eunit/ebin/eunit_server.beam +0 -0
  151. data/lib/erlang/messenger/lib/eunit/ebin/eunit_striptests.beam +0 -0
  152. data/lib/erlang/messenger/lib/eunit/ebin/eunit_test.beam +0 -0
  153. data/lib/erlang/messenger/lib/eunit/ebin/eunit_tests.beam +0 -0
  154. data/lib/erlang/messenger/lib/eunit/ebin/eunit_tty.beam +0 -0
  155. data/lib/erlang/messenger/lib/eunit/ebin/file_monitor.beam +0 -0
  156. data/lib/erlang/messenger/lib/eunit/src/Makefile +0 -46
  157. data/lib/poolparty/config/allowed_commands.yml +0 -1
  158. data/lib/poolparty/plugins/git.rb +0 -45
  159. data/spec/poolparty/plugins/git_spec.rb +0 -40
@@ -0,0 +1,259 @@
1
+ 8
2
+
3
+ dir
4
+ 263
5
+ http://svn.process-one.net/contribs/trunk/eunit/src
6
+ http://svn.process-one.net/contribs
7
+
8
+
9
+
10
+ 2008-10-02T07:09:39.920718Z
11
+ 258
12
+ rcarlsson
13
+
14
+
15
+ svn:special svn:externals svn:needs-lock
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+ 5c723cce-c907-0410-9aa2-ab8348fff7a4
28
+
29
+ eunit_tests.erl
30
+ file
31
+
32
+
33
+
34
+
35
+ 2008-10-18T23:25:36.000000Z
36
+ 7bf5a76dd440923990c7b484df953d88
37
+ 2007-11-15T10:23:54.688786Z
38
+ 238
39
+ mremond
40
+ has-props
41
+
42
+ eunit_proc.erl
43
+ file
44
+
45
+
46
+
47
+
48
+ 2008-10-18T23:25:36.000000Z
49
+ 03043c0e066a109082097aef890fc37c
50
+ 2008-09-29T17:42:21.837614Z
51
+ 256
52
+ rcarlsson
53
+ has-props
54
+
55
+ autoload.erl
56
+ file
57
+
58
+
59
+
60
+
61
+ 2008-10-18T23:25:36.000000Z
62
+ 5e5050f0ad965ea25cb9ad302da9a217
63
+ 2007-11-15T10:23:54.688786Z
64
+ 238
65
+ mremond
66
+ has-props
67
+
68
+ eunit.app.src
69
+ file
70
+
71
+
72
+
73
+
74
+ 2008-10-18T23:25:36.000000Z
75
+ 3cf609893ad581006db46c7faccc018e
76
+ 2007-05-05T14:47:04.988837Z
77
+ 211
78
+ rcarlsson
79
+
80
+ eunit_server.erl
81
+ file
82
+
83
+
84
+
85
+
86
+ 2008-10-18T23:25:36.000000Z
87
+ dbc03f7a823600ddee4be9a1b9390a44
88
+ 2007-11-15T10:23:54.688786Z
89
+ 238
90
+ mremond
91
+ has-props
92
+
93
+ eunit_lib.erl
94
+ file
95
+
96
+
97
+
98
+
99
+ 2008-10-18T23:25:36.000000Z
100
+ e56a109d2b0ca2a4f0fea79b171345c0
101
+ 2007-11-15T10:23:54.688786Z
102
+ 238
103
+ mremond
104
+ has-props
105
+
106
+ eunit_data.erl
107
+ file
108
+
109
+
110
+
111
+
112
+ 2008-10-18T23:25:36.000000Z
113
+ 9991ae2d9a13cc8daa2afa605687459f
114
+ 2008-09-29T17:13:43.707110Z
115
+ 253
116
+ rcarlsson
117
+ has-props
118
+
119
+ eunit.appup.src
120
+ file
121
+
122
+
123
+
124
+
125
+ 2008-10-18T23:25:36.000000Z
126
+ cb8fccb1c3eb4716a1497a2acaca200b
127
+ 2007-05-05T14:47:04.988837Z
128
+ 211
129
+ rcarlsson
130
+
131
+ eunit_autoexport.erl
132
+ file
133
+
134
+
135
+
136
+
137
+ 2008-10-18T23:25:36.000000Z
138
+ 5d1044347abc3dea56ca96165172ef6e
139
+ 2008-10-02T07:09:39.920718Z
140
+ 258
141
+ rcarlsson
142
+ has-props
143
+
144
+ code_monitor.erl
145
+ file
146
+
147
+
148
+
149
+
150
+ 2008-10-18T23:25:36.000000Z
151
+ f572097b0ec7cafd2089f56a5eb7f9fe
152
+ 2007-11-15T10:23:54.688786Z
153
+ 238
154
+ mremond
155
+ has-props
156
+
157
+ eunit_serial.erl
158
+ file
159
+
160
+
161
+
162
+
163
+ 2008-10-18T23:25:36.000000Z
164
+ cbef3435db2217b039b3a2c5ac1a9b4f
165
+ 2008-05-11T20:06:45.605499Z
166
+ 249
167
+ rcarlsson
168
+ has-props
169
+
170
+ eunit_internal.hrl
171
+ file
172
+
173
+
174
+
175
+
176
+ 2008-10-18T23:25:36.000000Z
177
+ 5004ef0c3c46afc59168be7f84f4d72e
178
+ 2007-11-15T10:23:54.688786Z
179
+ 238
180
+ mremond
181
+ has-props
182
+
183
+ eunit_test.erl
184
+ file
185
+
186
+
187
+
188
+
189
+ 2008-10-18T23:25:36.000000Z
190
+ 5002627123543a66a63ae39c2a9b8241
191
+ 2007-11-15T10:23:54.688786Z
192
+ 238
193
+ mremond
194
+ has-props
195
+
196
+ eunit.erl
197
+ file
198
+
199
+
200
+
201
+
202
+ 2008-10-18T23:25:36.000000Z
203
+ 6f5f15caa627e0ae275ccadcfc028acc
204
+ 2008-05-11T20:06:45.605499Z
205
+ 249
206
+ rcarlsson
207
+ has-props
208
+
209
+ eunit_tty.erl
210
+ file
211
+
212
+
213
+
214
+
215
+ 2008-10-18T23:25:36.000000Z
216
+ 81a970f0ac5baf4bb85175b7e135f1aa
217
+ 2007-11-15T10:23:54.688786Z
218
+ 238
219
+ mremond
220
+ has-props
221
+
222
+ file_monitor.erl
223
+ file
224
+
225
+
226
+
227
+
228
+ 2008-10-18T23:25:36.000000Z
229
+ f2f7a2d45511f1990ed14e243bfaf563
230
+ 2008-08-23T09:12:02.363609Z
231
+ 250
232
+ rcarlsson
233
+ has-props
234
+
235
+ eunit_striptests.erl
236
+ file
237
+
238
+
239
+
240
+
241
+ 2008-10-18T23:25:36.000000Z
242
+ 1c4d2c7395132297628b6774ab39d327
243
+ 2007-11-15T10:23:54.688786Z
244
+ 238
245
+ mremond
246
+ has-props
247
+
248
+ Makefile
249
+ file
250
+
251
+
252
+
253
+
254
+ 2008-10-18T23:25:36.000000Z
255
+ eb300b5f8d4ca4ce302536227aaf97fb
256
+ 2008-01-31T21:22:36.813745Z
257
+ 245
258
+ rcarlsson
259
+
@@ -0,0 +1,5 @@
1
+ K 12
2
+ svn:keywords
3
+ V 31
4
+ Date Author Id Revision HeadURL
5
+ END
@@ -0,0 +1,5 @@
1
+ K 12
2
+ svn:keywords
3
+ V 31
4
+ Date Author Id Revision HeadURL
5
+ END
@@ -0,0 +1,5 @@
1
+ K 12
2
+ svn:keywords
3
+ V 31
4
+ Date Author Id Revision HeadURL
5
+ END
@@ -0,0 +1,5 @@
1
+ K 12
2
+ svn:keywords
3
+ V 31
4
+ Date Author Id Revision HeadURL
5
+ END
@@ -0,0 +1,5 @@
1
+ K 12
2
+ svn:keywords
3
+ V 31
4
+ Date Author Id Revision HeadURL
5
+ END
@@ -0,0 +1,5 @@
1
+ K 12
2
+ svn:keywords
3
+ V 31
4
+ Date Author Id Revision HeadURL
5
+ END
@@ -0,0 +1,5 @@
1
+ K 12
2
+ svn:keywords
3
+ V 31
4
+ Date Author Id Revision HeadURL
5
+ END
@@ -0,0 +1,5 @@
1
+ K 12
2
+ svn:keywords
3
+ V 31
4
+ Date Author Id Revision HeadURL
5
+ END
@@ -0,0 +1,5 @@
1
+ K 12
2
+ svn:keywords
3
+ V 31
4
+ Date Author Id Revision HeadURL
5
+ END
@@ -0,0 +1,5 @@
1
+ K 12
2
+ svn:keywords
3
+ V 31
4
+ Date Author Id Revision HeadURL
5
+ END
@@ -0,0 +1,5 @@
1
+ K 12
2
+ svn:keywords
3
+ V 31
4
+ Date Author Id Revision HeadURL
5
+ END
@@ -0,0 +1,5 @@
1
+ K 12
2
+ svn:keywords
3
+ V 31
4
+ Date Author Id Revision HeadURL
5
+ END
@@ -0,0 +1,5 @@
1
+ K 12
2
+ svn:keywords
3
+ V 31
4
+ Date Author Id Revision HeadURL
5
+ END
@@ -0,0 +1,5 @@
1
+ K 12
2
+ svn:keywords
3
+ V 31
4
+ Date Author Id Revision HeadURL
5
+ END
@@ -0,0 +1,5 @@
1
+ K 12
2
+ svn:keywords
3
+ V 31
4
+ Date Author Id Revision HeadURL
5
+ END
@@ -0,0 +1,388 @@
1
+ %% This library is free software; you can redistribute it and/or modify
2
+ %% it under the terms of the GNU Lesser General Public License as
3
+ %% published by the Free Software Foundation; either version 2 of the
4
+ %% License, or (at your option) any later version.
5
+ %%
6
+ %% This library is distributed in the hope that it will be useful, but
7
+ %% WITHOUT ANY WARRANTY; without even the implied warranty of
8
+ %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9
+ %% Lesser General Public License for more details.
10
+ %%
11
+ %% You should have received a copy of the GNU Lesser General Public
12
+ %% License along with this library; if not, write to the Free Software
13
+ %% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
14
+ %% USA
15
+ %%
16
+ %% $Id:$
17
+ %%
18
+ %% @private (for now)
19
+ %% @author Richard Carlsson <richardc@it.uu.se>
20
+ %% @copyright 2006 Richard Carlsson
21
+ %% @doc Erlang automatic code loading service
22
+
23
+ -module(autoload).
24
+
25
+ -export([start/0, start/1, stop/0, stop/1,
26
+ watch_module/1, watch_module/2, watch_module/3,
27
+ watch_file/1, watch_file/2, watch_file/3,
28
+ watch_dir/1, watch_dir/2, watch_dir/3
29
+ ]).
30
+
31
+ -include_lib("kernel/include/file.hrl").
32
+
33
+ -define(SERVER, autoload).
34
+ -define(ZERO_TIMESTAMP, {0,0,0}).
35
+
36
+ %% TODO: un-watching functionality
37
+
38
+ %% We're not trying to provide strong guarantees here. The autoloader is
39
+ %% supposed to behave like a human assistant might - race conditions may
40
+ %% cause modules to be reloaded twice, or cause a reload from the wrong
41
+ %% file (if paths are suddenly changed).
42
+
43
+
44
+ watch_dir(Path) ->
45
+ watch_dir(Path, []).
46
+
47
+ watch_dir(Path, Opts) ->
48
+ watch_dir(?SERVER, Path, Opts).
49
+
50
+ watch_dir(Server, Path, Opts) ->
51
+ command(Server, {watch, {dir, filename:flatten(Path)}, Opts}).
52
+
53
+ watch_file(Path) ->
54
+ watch_file(Path, []).
55
+
56
+ watch_file(Path, Opts) ->
57
+ watch_file(?SERVER, Path, Opts).
58
+
59
+ watch_file(Server, Path, Opts) ->
60
+ command(Server, {watch, {file, filename:flatten(Path)}, Opts}).
61
+
62
+ watch_module(Module) ->
63
+ watch_module(Module, []).
64
+
65
+ watch_module(Module, Opts) ->
66
+ watch_module(?SERVER, Module, Opts).
67
+
68
+ watch_module(Server, Module, Opts) when is_atom(Module) ->
69
+ command(Server, {watch, {module, Module}, Opts}).
70
+
71
+
72
+ command(Server, Msg) ->
73
+ ServerPid = ensure_started(Server),
74
+ ServerPid ! {command, self(), Msg},
75
+ receive
76
+ {ServerPid, Result} -> Result
77
+ end.
78
+
79
+ stop() ->
80
+ stop(?SERVER).
81
+
82
+ stop(Server) ->
83
+ Server ! stop,
84
+ ok.
85
+
86
+ ensure_started(Name) when is_atom(Name) ->
87
+ start(Name);
88
+ ensure_started(Pid) when is_pid(Pid) ->
89
+ Pid.
90
+
91
+
92
+ start() ->
93
+ start(?SERVER).
94
+
95
+ start(Name) ->
96
+ case whereis(Name) of
97
+ undefined ->
98
+ Parent = self(),
99
+ Pid = spawn(fun () -> server_init(Name, Parent) end),
100
+ receive
101
+ {Pid, ok} -> Pid;
102
+ {Pid, error} -> throw(no_server)
103
+ end;
104
+ Pid -> Pid
105
+ end.
106
+
107
+ -record(state, {name, modules, files, dirs}).
108
+
109
+ -record(module, {time = ?ZERO_TIMESTAMP, file, opts = []}).
110
+
111
+ server_init(Name, Parent) ->
112
+ Self = self(),
113
+ case catch register(Name, Self) of
114
+ true ->
115
+ Parent ! {Self, ok},
116
+ code_monitor:monitor(self()),
117
+ server(#state{name = Name,
118
+ modules = dict:new(),
119
+ files = dict:new(),
120
+ dirs = dict:new()});
121
+ _ ->
122
+ init_failure(Parent)
123
+ end.
124
+
125
+ init_failure(Parent) ->
126
+ Parent ! {self(), error},
127
+ exit(failed).
128
+
129
+ server(St) ->
130
+ receive
131
+ {file_monitor, _Ref, Msg} ->
132
+ file_event(Msg, St);
133
+ {code_monitor, Msg} ->
134
+ code_event(Msg, St);
135
+ {command, From, Cmd} ->
136
+ server_command(From, Cmd, St);
137
+ stop ->
138
+ exit(normal);
139
+ Msg ->
140
+ erlang:display({autoload_unexpected, Msg}),
141
+ server(St)
142
+ end.
143
+
144
+ server_command_reply(From, Msg) ->
145
+ From ! {self(), Msg}.
146
+
147
+ server_command(From, {watch, {dir, Path}, Opts}, St) ->
148
+ server_command_reply(From, ok),
149
+ server(monitor_dir(Path, Opts, St));
150
+ server_command(From, {watch, {file, Path}, Opts}, St) ->
151
+ server_command_reply(From, ok),
152
+ server(monitor_file(Path, Opts, St));
153
+ server_command(From, {watch, {module, M}, Opts}, St) ->
154
+ server_command_reply(From, ok),
155
+ server(monitor_module(M, Opts, St)).
156
+
157
+ file_event({exists, Path, dir, _Info, Files}, St) ->
158
+ %%erlang:display({autoload_saw_exists, dir, Path}),
159
+ server(monitor_objs(Path, Files, St));
160
+ file_event({exists, Path, file, Info, _}, St) ->
161
+ %%erlang:display({autoload_saw_exists, file, Path}),
162
+ %% treat file-exists messages just like file-changed messages
163
+ server(changed_file(Path, Info#file_info.mtime, St));
164
+ file_event({changed, Path, dir, _Info, Files}, St) ->
165
+ %%erlang:display({autoload_saw_changed, dir, Path}),
166
+ server(monitor_objs(Path, Files, St));
167
+ file_event({changed, Path, file, #file_info{}=Info, _}, St) ->
168
+ %%erlang:display({autoload_saw_changed, file, Path}),
169
+ server(changed_file(Path, Info#file_info.mtime, St));
170
+ file_event({error, _Path, file, _ErrorAtom}=_Msg, St) ->
171
+ %%erlang:display({autoload_ignoring, _Msg}),
172
+ %% just consider the files as being temporarily unavailable
173
+ server(St);
174
+ file_event(_Msg, St) ->
175
+ erlang:display({autoload_unexpected_file_event, _Msg}),
176
+ server(St).
177
+
178
+ code_event({loaded, M, Time}, St) ->
179
+ %%erlang:display({autoload_saw_loaded, M, Time}),
180
+ server(loaded_module(M, Time, St));
181
+ code_event(_Msg, St) ->
182
+ erlang:display({autoload_unexpected_code_event, _Msg}),
183
+ server(St).
184
+
185
+
186
+ %% called when asked to watch a module M
187
+
188
+ monitor_module(M, Opts, St) ->
189
+ ensure_loaded(M, "", Opts),
190
+ case code:which(M) of
191
+ non_existing ->
192
+ %% no module loaded or found in path (e.g., the user has not
193
+ %% run 'make' yet, or has not updated the path): store
194
+ %% mapping from M to undefined file, for late binding
195
+ store_record(M, #module{opts = Opts}, St);
196
+ File when is_list(File) ->
197
+ %% existing file found (already loaded or in path): monitor
198
+ %% the file and map M to that file (even if the first load
199
+ %% might turn out to be from another file)
200
+ store_record(M, #module{file = File},
201
+ monitor_file(File, Opts, St));
202
+ _ ->
203
+ %% preloaded or cover-compiled module - ignore
204
+ St
205
+ end.
206
+
207
+ %% called when a monitored directory is detected as new or changed
208
+
209
+ monitor_objs(Path, Files, St) ->
210
+ Opts = get_dir_opts(Path, St),
211
+ ObjExt = file:objfile_extension(),
212
+ Objs = [F || {added, F} <- Files, filename:extension(F) == ObjExt],
213
+ lists:foldl(
214
+ fun (F, St) ->
215
+ F1 = filename:absname(filename:join(Path, F)),
216
+ %%erlang:display({autoload_monitoring, file, F1}),
217
+ monitor_file(F1, Opts, St)
218
+ end,
219
+ St,
220
+ Objs).
221
+
222
+ get_dir_opts(Path, St) ->
223
+ case dict:find(Path, St#state.dirs) of
224
+ {ok, {_Ref, Opts}} -> Opts;
225
+ error -> []
226
+ end.
227
+
228
+ %% called when a module was detected as loaded or reloaded (either
229
+ %% caused by an auto-load or by someone else)
230
+
231
+ loaded_module(M, Time, St) ->
232
+ case find_record(M, St) of
233
+ {ok, R} ->
234
+ File = code:which(M),
235
+ case R#module.file of
236
+ undefined when is_list(File) ->
237
+ %% a watched module gets a late binding to a file
238
+ %%erlang:display({autoload_late_binding, M, File}),
239
+ Opts = R#module.opts,
240
+ update_record(M, R, Time, File,
241
+ monitor_file(File, Opts, St));
242
+ File when is_list(File) ->
243
+ %% loaded from watched file - update the load time
244
+ update_record(M, R, Time, File, St);
245
+ _ ->
246
+ St %% not loaded from the watched file
247
+ end;
248
+ error ->
249
+ St %% uninteresting module
250
+ end.
251
+
252
+
253
+ %% called whenever a file has changed and exists
254
+
255
+ changed_file(File, Time, St) ->
256
+ %% always reread the module name from the file
257
+ case obj_module(File) of
258
+ {module, M} ->
259
+ case find_record(M, St) of
260
+ {ok, R} ->
261
+ check_reload(M, File, Time, R),
262
+ St;
263
+ error ->
264
+ %% first time we see this module: map to file
265
+ %% and don't try to reload
266
+ R = #module{file = File},
267
+ store_record(M, R, St)
268
+ end;
269
+ error ->
270
+ St %% bad file - ignore until changed again
271
+ end.
272
+
273
+
274
+ %% check if a module needs to be reloaded, when its file has changed
275
+
276
+ check_reload(M, File, Time, R) ->
277
+ %%erlang:display({autoload_checking, M, File, Time, R}),
278
+ case ((R#module.file == File)
279
+ andalso is_loaded(M)
280
+ andalso (code:which(M) == File)
281
+ andalso is_newer(Time, R#module.time))
282
+ of
283
+ true ->
284
+ reload(M);
285
+ false ->
286
+ ok
287
+ end.
288
+
289
+
290
+ reload(M) ->
291
+ erlang:display({autoload_loading, M}),
292
+ code:purge(M),
293
+ code:load_file(M).
294
+
295
+ update_record(M, R, Time, File, St) ->
296
+ store_record(M, R#module{time = Time, file = File}, St).
297
+
298
+ find_record(M, St) ->
299
+ dict:find(M, St#state.modules).
300
+
301
+ store_record(M, R, St) ->
302
+ St#state{modules = dict:store(M, R, St#state.modules)}.
303
+
304
+ %% we must remember watched files/dirs, so we don't set up more than one
305
+ %% file monitor for the same path, and so we can cancel monitors; for
306
+ %% dirs, we also remember options
307
+
308
+ monitor_file(Path, Opts, St) ->
309
+ ensure_loaded([], Path, Opts),
310
+ case dict:is_key(Path, St#state.files) of
311
+ true ->
312
+ %%erlang:display({autoload_already_watching, Path}),
313
+ St;
314
+ false ->
315
+ {ok, _, Ref} = file_monitor:monitor_file(Path, self()),
316
+ St#state{files = dict:store(Path, Ref, St#state.files)}
317
+ end.
318
+
319
+ monitor_dir(Path, Opts, St) ->
320
+ case dict:is_key(Path, St#state.dirs) of
321
+ true ->
322
+ %%erlang:display({autoload_already_watching, Path}),
323
+ St;
324
+ false ->
325
+ {ok, _, Ref} = file_monitor:monitor_dir(Path, self()),
326
+ St#state{dirs = dict:store(Path, {Ref, Opts},
327
+ St#state.dirs)}
328
+ end.
329
+
330
+ %% try to ensure that a module/file is loaded (M is [] if unknown;
331
+ %% File is "" if unknown)
332
+
333
+ ensure_loaded(M, File, Opts) ->
334
+ case proplists:get_bool(load, Opts) of
335
+ true when is_atom(M) ->
336
+ ensure_loaded_1(M, File); %% known module name
337
+ true when M == [] ->
338
+ case obj_module(File) of
339
+ {module, Module} ->
340
+ ensure_loaded_1(Module, File);
341
+ error ->
342
+ ok %% couldn't load
343
+ end;
344
+ false -> ok
345
+ end.
346
+
347
+ ensure_loaded_1(M, File) ->
348
+ %% always try to load using the path first
349
+ case code:ensure_loaded(M) of
350
+ {module, _} ->
351
+ ok;
352
+ {error, _} when File == [] ->
353
+ ok; %% ignore error
354
+ {error, _} ->
355
+ %% try loading directly from the file
356
+ code:load_abs(File) %% ignore result
357
+ end.
358
+
359
+ %% find name of module stored in an object file
360
+
361
+ obj_module(File) ->
362
+ case beam_lib:info(File) of
363
+ List when is_list(List) ->
364
+ case lists:keysearch(module, 1, List) of
365
+ {value, {module, M}} ->
366
+ {module, M};
367
+ _ ->
368
+ error
369
+ end;
370
+ _ ->
371
+ error
372
+ end.
373
+
374
+ %% check if the file timestamp (on DateTime format) is newer than
375
+ %% the module load-time (on Now-format)
376
+
377
+ is_newer(DateTime, LoadTime) ->
378
+ calendar:datetime_to_gregorian_seconds(DateTime) >
379
+ calendar:datetime_to_gregorian_seconds(
380
+ calendar:now_to_local_time(LoadTime)).
381
+
382
+ %% wrapper for code:is_loaded/1
383
+
384
+ is_loaded(Module) ->
385
+ case code:is_loaded(Module) of
386
+ {file, _} -> true;
387
+ false -> false
388
+ end.