inochi 0.3.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/CREDITS +1 -0
  2. data/bin/inochi +112 -104
  3. data/doc/api/classes/Array.html +370 -0
  4. data/doc/api/classes/File.html +110 -0
  5. data/doc/api/classes/Inochi.html +1493 -0
  6. data/doc/api/classes/Inochi/Manual.html +157 -0
  7. data/doc/api/classes/Inochi/Phrases.html +331 -0
  8. data/doc/api/classes/Inochi/Version.html +190 -0
  9. data/doc/api/classes/TempDir.html +164 -0
  10. data/doc/api/created.rid +1 -0
  11. data/doc/api/css/main.css +263 -0
  12. data/doc/api/css/panel.css +383 -0
  13. data/doc/api/css/reset.css +53 -0
  14. data/doc/api/files/CREDITS.html +61 -0
  15. data/doc/api/files/LICENSE.html +76 -0
  16. data/doc/api/files/lib/inochi/book_rb.html +96 -0
  17. data/doc/api/files/lib/inochi/init_rb.html +78 -0
  18. data/doc/api/files/lib/inochi/main_rb.html +52 -0
  19. data/doc/api/files/lib/inochi/rake_rb.html +52 -0
  20. data/doc/api/files/lib/inochi/test/bacon_rb.html +67 -0
  21. data/doc/api/files/lib/inochi/test/context_rb.html +69 -0
  22. data/doc/api/files/lib/inochi/test/dfect_rb.html +67 -0
  23. data/doc/api/files/lib/inochi/test/matchy_rb.html +69 -0
  24. data/doc/api/files/lib/inochi/test/minitest_rb.html +71 -0
  25. data/doc/api/files/lib/inochi/test/mocha_rb.html +67 -0
  26. data/doc/api/files/lib/inochi/test/rspec_rb.html +67 -0
  27. data/doc/api/files/lib/inochi/test/shoulda_rb.html +67 -0
  28. data/doc/api/files/lib/inochi/test/test_spec_rb.html +67 -0
  29. data/doc/api/files/lib/inochi/test/test_unit_rb.html +67 -0
  30. data/doc/api/files/lib/inochi/util/combo_rb.html +59 -0
  31. data/doc/api/files/lib/inochi/util/tempdir_rb.html +68 -0
  32. data/doc/api/files/lib/inochi/util_rb.html +59 -0
  33. data/doc/api/files/lib/inochi_rb.html +78 -0
  34. data/doc/api/i/arrows.png +0 -0
  35. data/doc/api/i/results_bg.png +0 -0
  36. data/doc/api/i/tree_bg.png +0 -0
  37. data/doc/api/index.html +14 -18
  38. data/doc/api/js/jquery-1.3.2.min.js +19 -0
  39. data/doc/api/js/jquery-effect.js +593 -0
  40. data/doc/api/js/main.js +22 -0
  41. data/doc/api/js/searchdoc.js +605 -0
  42. data/doc/api/panel/index.html +63 -0
  43. data/doc/api/panel/search_index.js +1 -0
  44. data/doc/api/panel/tree.js +1 -0
  45. data/doc/history.erb +75 -34
  46. data/doc/index.erb +10 -5
  47. data/doc/index.xhtml +806 -1145
  48. data/doc/intro.erb +33 -27
  49. data/doc/setup.erb +16 -15
  50. data/doc/usage.erb +86 -137
  51. data/lib/inochi.rb +25 -13
  52. data/lib/inochi/book.rb +13 -6
  53. data/lib/inochi/init.rb +41 -24
  54. data/lib/inochi/main.rb +17 -7
  55. data/lib/inochi/rake.rb +200 -59
  56. data/lib/inochi/test/bacon.rb +3 -0
  57. data/lib/inochi/test/context.rb +4 -0
  58. data/lib/inochi/test/dfect.rb +3 -0
  59. data/lib/inochi/test/matchy.rb +4 -0
  60. data/lib/inochi/test/minitest.rb +7 -0
  61. data/lib/inochi/test/mocha.rb +3 -0
  62. data/lib/inochi/test/rspec.rb +3 -0
  63. data/lib/inochi/test/shoulda.rb +3 -0
  64. data/lib/inochi/test/test_spec.rb +3 -0
  65. data/lib/inochi/test/test_unit.rb +3 -0
  66. data/lib/inochi/util.rb +23 -1
  67. data/lib/inochi/util/combo.rb +191 -0
  68. data/lib/inochi/util/tempdir.rb +29 -0
  69. data/rakefile +12 -0
  70. data/test/inochi.rb +5 -0
  71. metadata +119 -45
  72. data/Rakefile +0 -6
  73. data/doc/api/Inochi.html +0 -2574
  74. data/doc/api/Inochi/Manual.html +0 -230
  75. data/doc/api/Inochi/Phrases.html +0 -409
  76. data/doc/api/Inochi/Version.html +0 -222
  77. data/doc/api/all-methods.html +0 -180
  78. data/doc/api/all-namespaces.html +0 -28
  79. data/doc/api/app.js +0 -18
  80. data/doc/api/jquery.js +0 -11
  81. data/doc/api/readme.html +0 -38
  82. data/doc/api/style.css +0 -68
  83. data/doc/api/syntax_highlight.css +0 -21
  84. data/doc/theory.erb +0 -3
@@ -0,0 +1,110 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+ <head>
6
+ <title>File</title>
7
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8
+ <link rel="stylesheet" href="../css/reset.css" type="text/css" media="screen" />
9
+ <link rel="stylesheet" href="../css/main.css" type="text/css" media="screen" />
10
+ <script src="../js/jquery-1.3.2.min.js" type="text/javascript" charset="utf-8"></script>
11
+ <script src="../js/jquery-effect.js" type="text/javascript" charset="utf-8"></script>
12
+ <script src="../js/main.js" type="text/javascript" charset="utf-8"></script>
13
+ </head>
14
+
15
+ <body>
16
+ <div class="banner">
17
+ <h1>
18
+ <span class="type">Class</span>
19
+ File
20
+
21
+ <span class="parent">&lt;
22
+
23
+ IO
24
+
25
+ </span>
26
+
27
+ </h1>
28
+ <ul class="files">
29
+
30
+ <li><a href="../files/lib/inochi/util_rb.html">lib/inochi/util.rb</a></li>
31
+
32
+ </ul>
33
+ </div>
34
+ <div id="bodyContent">
35
+ <div id="content">
36
+
37
+
38
+
39
+
40
+
41
+
42
+
43
+
44
+
45
+ <div class="sectiontitle">Methods</div>
46
+ <dl class="methods">
47
+
48
+ <dt>W</dt>
49
+ <dd>
50
+ <ul>
51
+
52
+ <li><a href="#M000021">write</a></li>
53
+
54
+ </ul>
55
+ </dd>
56
+
57
+ </dl>
58
+
59
+
60
+
61
+
62
+
63
+
64
+
65
+
66
+
67
+
68
+
69
+
70
+
71
+ <div class="sectiontitle">Class Public methods</div>
72
+
73
+ <div class="method">
74
+ <div class="title" id="M000021">
75
+
76
+ <a name="M000021"></a><b>write</b>(path, content)
77
+
78
+ </div>
79
+
80
+ <div class="description">
81
+ <p>
82
+ Writes the given content to the given file.
83
+ </p>
84
+
85
+ </div>
86
+
87
+
88
+
89
+
90
+ <div class="sourcecode">
91
+ <p class="source-link">
92
+ Source: <a href="javascript:toggleSource('M000021_source')" id="l_M000021_source">show</a>
93
+
94
+ | <a href="http://github.com/sunaku/inochi/blob/61f28653cea6fab1bfd8cffb07a666c236b243be/lib/inochi/util.rb#L96" target="_blank" class="github_url">on GitHub</a>
95
+
96
+ </p>
97
+ <div id="M000021_source" class="dyn-source">
98
+ <pre><span class="ruby-comment cmt"># File lib/inochi/util.rb, line 96</span>
99
+ <span class="ruby-keyword kw">def</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">write</span> <span class="ruby-identifier">path</span>, <span class="ruby-identifier">content</span>
100
+ <span class="ruby-identifier">open</span>(<span class="ruby-identifier">path</span>, <span class="ruby-value str">'wb'</span>) {<span class="ruby-operator">|</span><span class="ruby-identifier">f</span><span class="ruby-operator">|</span> <span class="ruby-identifier">f</span>.<span class="ruby-identifier">write</span> <span class="ruby-identifier">content</span> }
101
+ <span class="ruby-keyword kw">end</span></pre>
102
+ </div>
103
+ </div>
104
+
105
+ </div>
106
+
107
+ </div>
108
+ </div>
109
+ </body>
110
+ </html>
@@ -0,0 +1,1493 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+ <head>
6
+ <title>Inochi</title>
7
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8
+ <link rel="stylesheet" href="../css/reset.css" type="text/css" media="screen" />
9
+ <link rel="stylesheet" href="../css/main.css" type="text/css" media="screen" />
10
+ <script src="../js/jquery-1.3.2.min.js" type="text/javascript" charset="utf-8"></script>
11
+ <script src="../js/jquery-effect.js" type="text/javascript" charset="utf-8"></script>
12
+ <script src="../js/main.js" type="text/javascript" charset="utf-8"></script>
13
+ </head>
14
+
15
+ <body>
16
+ <div class="banner">
17
+ <h1>
18
+ <span class="type">Module</span>
19
+ Inochi
20
+
21
+ </h1>
22
+ <ul class="files">
23
+
24
+ <li><a href="../files/lib/inochi_rb.html">lib/inochi.rb</a></li>
25
+
26
+ <li><a href="../files/lib/inochi/book_rb.html">lib/inochi/book.rb</a></li>
27
+
28
+ <li><a href="../files/lib/inochi/init_rb.html">lib/inochi/init.rb</a></li>
29
+
30
+ </ul>
31
+ </div>
32
+ <div id="bodyContent">
33
+ <div id="content">
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+
43
+ <div class="sectiontitle">Methods</div>
44
+ <dl class="methods">
45
+
46
+ <dt>B</dt>
47
+ <dd>
48
+ <ul>
49
+
50
+ <li><a href="#M000011">book</a></li>
51
+
52
+ </ul>
53
+ </dd>
54
+
55
+ <dt>I</dt>
56
+ <dd>
57
+ <ul>
58
+
59
+ <li><a href="#M000022">init</a></li>
60
+
61
+ </ul>
62
+ </dd>
63
+
64
+ <dt>M</dt>
65
+ <dd>
66
+ <ul>
67
+
68
+ <li><a href="#M000010">main</a></li>
69
+
70
+ </ul>
71
+ </dd>
72
+
73
+ <dt>R</dt>
74
+ <dd>
75
+ <ul>
76
+
77
+ <li><a href="#M000014">rake</a></li>
78
+
79
+ </ul>
80
+ </dd>
81
+
82
+ </dl>
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+ <div class="sectiontitle">Classes and Modules</div>
91
+ <ul>
92
+
93
+ <li><span class="type">MODULE</span> <a href="Inochi/Manual.html">Inochi::Manual</a></li>
94
+
95
+ <li><span class="type">MODULE</span> <a href="Inochi/Version.html">Inochi::Version</a></li>
96
+
97
+ <li><span class="type">CLASS</span> <a href="Inochi/Phrases.html">Inochi::Phrases</a></li>
98
+
99
+ </ul>
100
+
101
+
102
+
103
+
104
+
105
+
106
+
107
+ <div class="sectiontitle">Class Public methods</div>
108
+
109
+ <div class="method">
110
+ <div class="title" id="M000011">
111
+
112
+ <a name="M000011"></a><b>book</b>(project_symbol, book_template)
113
+
114
+ </div>
115
+
116
+ <div class="description">
117
+ <p>
118
+ Provides a common configuration for the project&#8217;s user manual:
119
+ </p>
120
+ <ul>
121
+ <li>Assigns the title, subtitle, date, and authors for the document.
122
+
123
+ <p>
124
+ You may override these assignments by reassigning these document parameters
125
+ AFTER this method is invoked.
126
+ </p>
127
+ <p>
128
+ Refer to the &#8220;document parameters&#8221; for the XHTML format in the
129
+ &#8220;erbook&#8221; user manual for details.
130
+ </p>
131
+ </li>
132
+ <li>Provides the project&#8217;s configuration as global variables in the
133
+ document.
134
+
135
+ <p>
136
+ For example, <%= $version %> is the same as <%= project_module::VERSION %>
137
+ in the document.
138
+ </p>
139
+ </li>
140
+ <li>Defines a &#8220;project_summary&#8220; node for use in the document. The
141
+ body of this node should contain a brief introduction to the project.
142
+
143
+ </li>
144
+ <li>Defines a &#8220;project_history&#8220; node for use in the document. The
145
+ body of this node should contain other nodes, each of which represent a
146
+ single set of release notes for one of the project&#8217;s releases.
147
+
148
+ </li>
149
+ </ul>
150
+ <p>
151
+ It is assumed that this method is called from within the <a
152
+ href="Inochi.html#M000014">Inochi.rake()</a> environment.
153
+ </p>
154
+ <h4>Parameters</h4>
155
+ <dl>
156
+ <dt>project_symbol</dt><dd>Name of the Ruby constant which serves as a namespace for the entire
157
+ project.
158
+
159
+ </dd>
160
+ <dt>book_template</dt><dd>The eRuby template which serves as the documentation for the project.
161
+
162
+ </dd>
163
+ </dl>
164
+
165
+ </div>
166
+
167
+
168
+
169
+
170
+ <div class="sourcecode">
171
+ <p class="source-link">
172
+ Source: <a href="javascript:toggleSource('M000011_source')" id="l_M000011_source">show</a>
173
+
174
+ | <a href="http://github.com/sunaku/inochi/blob/5f65225f952717327ab0d21f371307dcd335f34c/lib/inochi/book.rb#L42" target="_blank" class="github_url">on GitHub</a>
175
+
176
+ </p>
177
+ <div id="M000011_source" class="dyn-source">
178
+ <pre><span class="ruby-comment cmt"># File lib/inochi/book.rb, line 42</span>
179
+ <span class="ruby-keyword kw">def</span> <span class="ruby-constant">Inochi</span>.<span class="ruby-identifier">book</span> <span class="ruby-identifier">project_symbol</span>, <span class="ruby-identifier">book_template</span>
180
+ <span class="ruby-identifier">project_module</span> = <span class="ruby-identifier">fetch_project_module</span>(<span class="ruby-identifier">project_symbol</span>)
181
+
182
+ <span class="ruby-comment cmt"># provide project constants as global variables to the user manual</span>
183
+ <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">INOCHI</span>.<span class="ruby-identifier">each_pair</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">param</span>, <span class="ruby-identifier">value</span><span class="ruby-operator">|</span>
184
+ <span class="ruby-identifier">eval</span> <span class="ruby-node">&quot;$#{param} = value&quot;</span>, <span class="ruby-identifier">binding</span>
185
+ <span class="ruby-keyword kw">end</span>
186
+
187
+ <span class="ruby-comment cmt"># set document parameters for the user manual</span>
188
+ <span class="ruby-identifier">$title</span> = <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">DISPLAY</span>
189
+ <span class="ruby-identifier">$subtitle</span> = <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">TAGLINE</span>
190
+ <span class="ruby-identifier">$feeds</span> = { <span class="ruby-constant">File</span>.<span class="ruby-identifier">join</span>(<span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">DOCSITE</span>, <span class="ruby-value str">'ann.xml'</span>) =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">:rss</span> }
191
+ <span class="ruby-identifier">$authors</span> = <span class="ruby-constant">Hash</span>[
192
+ <span class="ruby-operator">*</span><span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">AUTHORS</span>.<span class="ruby-identifier">map</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">name</span>, <span class="ruby-identifier">addr</span><span class="ruby-operator">|</span>
193
+ <span class="ruby-comment cmt"># convert raw e-mail addresses into URLs for the erbook XHTML format</span>
194
+ <span class="ruby-identifier">addr</span> = <span class="ruby-node">&quot;mailto:#{addr}&quot;</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">addr</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/^\w+:/</span>
195
+
196
+ [<span class="ruby-identifier">name</span>, <span class="ruby-identifier">addr</span>]
197
+ <span class="ruby-keyword kw">end</span>.<span class="ruby-identifier">flatten</span>
198
+ ]
199
+
200
+ <span class="ruby-identifier">book_template</span>.<span class="ruby-identifier">extend</span> <span class="ruby-constant">Manual</span>
201
+ <span class="ruby-keyword kw">end</span></pre>
202
+ </div>
203
+ </div>
204
+
205
+ </div>
206
+
207
+ <div class="method">
208
+ <div class="title" id="M000022">
209
+
210
+ <a name="M000022"></a><b>init</b>(project_symbol, project_config = {})
211
+
212
+ </div>
213
+
214
+ <div class="description">
215
+ <p>
216
+ Establishes your project in Ruby&#8217;s runtime environment by defining
217
+ the project module (which serves as a namespace for all code in the
218
+ project) and providing a common configuration for the project module:
219
+ </p>
220
+ <ul>
221
+ <li>Adds the project lib/ directory to the Ruby load path.
222
+
223
+ </li>
224
+ <li>Defines the INOCHI constant in the project module. This constant contains
225
+ the effective configuration parameters (@see project_config).
226
+
227
+ </li>
228
+ <li>Defines all configuration parameters as constants in the project module.
229
+
230
+ </li>
231
+ </ul>
232
+ <p>
233
+ This method must be invoked from immediately within (that is, not from
234
+ within any of its descendant directories) the project lib/ directory.
235
+ Ideally, this method would be invoked from the main project library.
236
+ </p>
237
+ <h4>Parameters</h4>
238
+ <dl>
239
+ <dt>project_symbol</dt><dd>Name of the Ruby constant which serves as a namespace for the entire
240
+ project.
241
+
242
+ </dd>
243
+ <dt>project_config</dt><dd>Optional hash of project configuration parameters:
244
+
245
+ <dl>
246
+ <dt>:project</dt><dd>Name of the project.
247
+
248
+ <p>
249
+ The default value is the value of the project_symbol parameter.
250
+ </p>
251
+ </dd>
252
+ <dt>:tagline</dt><dd>An enticing, single line description of the project.
253
+
254
+ <p>
255
+ The default value is an empty string.
256
+ </p>
257
+ </dd>
258
+ <dt>:website</dt><dd>URL of the published project website.
259
+
260
+ <p>
261
+ The default value is an empty string.
262
+ </p>
263
+ </dd>
264
+ <dt>:docsite</dt><dd>URL of the published user manual.
265
+
266
+ <p>
267
+ The default value is the same value as the :website parameter.
268
+ </p>
269
+ </dd>
270
+ <dt>:program</dt><dd>Name of the main project executable.
271
+
272
+ <p>
273
+ The default value is the value of the :project parameter in lowercase and
274
+ CamelCase converted into snake_case.
275
+ </p>
276
+ </dd>
277
+ <dt>:version</dt><dd><a href="Inochi/Version.html">Version</a> of the project.
278
+
279
+ <p>
280
+ The default value is &#8220;0.0.0&#8220;.
281
+ </p>
282
+ </dd>
283
+ <dt>:release</dt><dd>Date when this version was released.
284
+
285
+ <p>
286
+ The default value is the current time.
287
+ </p>
288
+ </dd>
289
+ <dt>:display</dt><dd>How the project name should be displayed.
290
+
291
+ <p>
292
+ The default value is the project name and version together.
293
+ </p>
294
+ </dd>
295
+ <dt>:install</dt><dd>Path to the directory which contains the project.
296
+
297
+ <p>
298
+ The default value is one directory above the parent directory of the file
299
+ from which this method was called.
300
+ </p>
301
+ </dd>
302
+ <dt>:require</dt><dd>Hash containing the names and version constraints of RubyGems required to
303
+ run this project. This information must be expressed as follows:
304
+
305
+ <ul>
306
+ <li>Each hash key must be the name of a ruby gem.
307
+
308
+ </li>
309
+ <li>Each hash value must be either <tt>nil</tt>, a single version number
310
+ requirement string (see Gem::Requirement) or an <a
311
+ href="Array.html">Array</a> thereof.
312
+
313
+ </li>
314
+ </ul>
315
+ <p>
316
+ The default value is an empty Hash.
317
+ </p>
318
+ </dd>
319
+ <dt>:develop</dt><dd>Hash containing the names and version constraints of RubyGems required to
320
+ build this project. This information must be expressed as follows:
321
+
322
+ <ul>
323
+ <li>Each hash key must be the name of a ruby gem.
324
+
325
+ </li>
326
+ <li>Each hash value must be either <tt>nil</tt>, a single version number
327
+ requirement string (see Gem::Requirement) or an <a
328
+ href="Array.html">Array</a> thereof.
329
+
330
+ </li>
331
+ </ul>
332
+ <p>
333
+ The default value is an empty Hash.
334
+ </p>
335
+ </dd>
336
+ </dl>
337
+ </dd>
338
+ </dl>
339
+ <h4>Returns</h4>
340
+ <p>
341
+ The newly configured project module.
342
+ </p>
343
+
344
+ </div>
345
+
346
+
347
+
348
+
349
+ <div class="sourcecode">
350
+ <p class="source-link">
351
+ Source: <a href="javascript:toggleSource('M000022_source')" id="l_M000022_source">show</a>
352
+
353
+ | <a href="http://github.com/sunaku/inochi/blob/61f28653cea6fab1bfd8cffb07a666c236b243be/lib/inochi/init.rb#L107" target="_blank" class="github_url">on GitHub</a>
354
+
355
+ </p>
356
+ <div id="M000022_source" class="dyn-source">
357
+ <pre><span class="ruby-comment cmt"># File lib/inochi/init.rb, line 107</span>
358
+ <span class="ruby-keyword kw">def</span> <span class="ruby-constant">Inochi</span>.<span class="ruby-identifier">init</span> <span class="ruby-identifier">project_symbol</span>, <span class="ruby-identifier">project_config</span> = {}
359
+ <span class="ruby-identifier">project_module</span> = <span class="ruby-identifier">fetch_project_module</span>(<span class="ruby-identifier">project_symbol</span>)
360
+
361
+ <span class="ruby-comment cmt"># this method is not re-entrant</span>
362
+ <span class="ruby-ivar">@already_seen</span> <span class="ruby-operator">||=</span> []
363
+ <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">project_module</span> <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@already_seen</span>.<span class="ruby-identifier">include?</span> <span class="ruby-identifier">project_module</span>
364
+ <span class="ruby-ivar">@already_seen</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">project_module</span>
365
+
366
+ <span class="ruby-comment cmt"># put project on Ruby load path</span>
367
+ <span class="ruby-identifier">project_file</span> = <span class="ruby-identifier">first_caller_file</span>
368
+ <span class="ruby-identifier">project_libs</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">dirname</span>(<span class="ruby-identifier">project_file</span>)
369
+ <span class="ruby-identifier">$LOAD_PATH</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">project_libs</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">$LOAD_PATH</span>.<span class="ruby-identifier">include?</span> <span class="ruby-identifier">project_libs</span>
370
+
371
+ <span class="ruby-comment cmt"># supply configuration defaults</span>
372
+ <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:project</span>] <span class="ruby-operator">||=</span> <span class="ruby-identifier">project_symbol</span>.<span class="ruby-identifier">to_s</span>
373
+ <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:tagline</span>] <span class="ruby-operator">||=</span> <span class="ruby-value str">''</span>
374
+ <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:version</span>] <span class="ruby-operator">||=</span> <span class="ruby-value str">'0.0.0'</span>
375
+ <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:release</span>] <span class="ruby-operator">||=</span> <span class="ruby-constant">Time</span>.<span class="ruby-identifier">now</span>.<span class="ruby-identifier">strftime</span>(<span class="ruby-value str">'%F'</span>)
376
+ <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:website</span>] <span class="ruby-operator">||=</span> <span class="ruby-value str">''</span>
377
+ <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:docsite</span>] <span class="ruby-operator">||=</span> <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:website</span>]
378
+ <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:display</span>] <span class="ruby-operator">||=</span> <span class="ruby-node">&quot;#{project_config[:project]} #{project_config[:version]}&quot;</span>
379
+ <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:program</span>] <span class="ruby-operator">||=</span> <span class="ruby-identifier">calc_program_name</span>(<span class="ruby-identifier">project_symbol</span>)
380
+ <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:install</span>] <span class="ruby-operator">||=</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">dirname</span>(<span class="ruby-identifier">project_libs</span>)
381
+ <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:require</span>] <span class="ruby-operator">||=</span> {}
382
+ <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:develop</span>] <span class="ruby-operator">||=</span> {}
383
+
384
+ <span class="ruby-comment cmt"># establish gem version dependencies and</span>
385
+ <span class="ruby-comment cmt"># sanitize the values while we're at it</span>
386
+ <span class="ruby-identifier">src</span> = <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:require</span>].<span class="ruby-identifier">dup</span>
387
+ <span class="ruby-identifier">dst</span> = <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:require</span>].<span class="ruby-identifier">clear</span>
388
+
389
+ <span class="ruby-identifier">src</span>.<span class="ruby-identifier">each_pair</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">gem_name</span>, <span class="ruby-identifier">version_reqs</span><span class="ruby-operator">|</span>
390
+ <span class="ruby-identifier">dst</span>[<span class="ruby-identifier">gem_name</span>] = <span class="ruby-identifier">require_gem_version</span>(<span class="ruby-identifier">gem_name</span>, <span class="ruby-identifier">version_reqs</span>)
391
+ <span class="ruby-keyword kw">end</span>
392
+
393
+ <span class="ruby-comment cmt"># make configuration parameters available as constants</span>
394
+ <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:inochi</span>] = <span class="ruby-identifier">project_config</span>
395
+ <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:phrases</span>] = <span class="ruby-constant">Phrases</span>.<span class="ruby-identifier">new</span> <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:install</span>]
396
+ <span class="ruby-identifier">project_config</span>[<span class="ruby-identifier">:version</span>].<span class="ruby-identifier">extend</span> <span class="ruby-constant">Version</span>
397
+
398
+ <span class="ruby-identifier">project_config</span>.<span class="ruby-identifier">each_pair</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">param</span>, <span class="ruby-identifier">value</span><span class="ruby-operator">|</span>
399
+ <span class="ruby-identifier">project_module</span>.<span class="ruby-identifier">const_set</span> <span class="ruby-identifier">param</span>.<span class="ruby-identifier">to_s</span>.<span class="ruby-identifier">upcase</span>, <span class="ruby-identifier">value</span>
400
+ <span class="ruby-keyword kw">end</span>
401
+
402
+ <span class="ruby-identifier">project_module</span>
403
+ <span class="ruby-keyword kw">end</span></pre>
404
+ </div>
405
+ </div>
406
+
407
+ </div>
408
+
409
+ <div class="method">
410
+ <div class="title" id="M000010">
411
+
412
+ <a name="M000010"></a><b>main</b>(project_symbol, *trollop_args, &amp;trollop_config)
413
+
414
+ </div>
415
+
416
+ <div class="description">
417
+ <p>
418
+ Provides a common configuration for the main project executable:
419
+ </p>
420
+ <ul>
421
+ <li>The program description (the sequence of non-blank lines at the top of the
422
+ file in which this method is invoked) is properly formatted and displayed
423
+ at the top of program&#8217;s help information.
424
+
425
+ </li>
426
+ <li>The program version information is fetched from the project module and
427
+ formatted in YAML fashion for easy consumption by other tools.
428
+
429
+ </li>
430
+ <li>A list of command-line options is displayed at the bottom of the
431
+ program&#8217;s help information.
432
+
433
+ </li>
434
+ </ul>
435
+ <p>
436
+ It is assumed that this method is invoked from only within the main project
437
+ executable (in the project bin/ directory).
438
+ </p>
439
+ <h4>Parameters</h4>
440
+ <dl>
441
+ <dt>project_symbol</dt><dd>Name of the Ruby constant which serves as a namespace for the entire
442
+ project.
443
+
444
+ </dd>
445
+ <dt>trollop_args</dt><dd>Optional array of arguments for Trollop::options().
446
+
447
+ </dd>
448
+ <dt>trollop_config</dt><dd>Optional block parameter passed to Trollop::options().
449
+
450
+ </dd>
451
+ </dl>
452
+ <p>
453
+ Returns the result of Trollop::options().
454
+ </p>
455
+
456
+ </div>
457
+
458
+
459
+
460
+
461
+ <div class="sourcecode">
462
+ <p class="source-link">
463
+ Source: <a href="javascript:toggleSource('M000010_source')" id="l_M000010_source">show</a>
464
+
465
+ | <a href="http://github.com/sunaku/inochi/blob/766b14740d2fffe75a0e4a11fd807c391e1f0c66/lib/inochi/main.rb#L36" target="_blank" class="github_url">on GitHub</a>
466
+
467
+ </p>
468
+ <div id="M000010_source" class="dyn-source">
469
+ <pre><span class="ruby-comment cmt"># File lib/inochi/main.rb, line 36</span>
470
+ <span class="ruby-keyword kw">def</span> <span class="ruby-constant">Inochi</span>.<span class="ruby-identifier">main</span> <span class="ruby-identifier">project_symbol</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">trollop_args</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">trollop_config</span>
471
+ <span class="ruby-identifier">program_file</span> = <span class="ruby-identifier">first_caller_file</span>
472
+ <span class="ruby-identifier">program_name</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">basename</span>(<span class="ruby-identifier">program_file</span>)
473
+ <span class="ruby-identifier">program_home</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">dirname</span>(<span class="ruby-constant">File</span>.<span class="ruby-identifier">dirname</span>(<span class="ruby-identifier">program_file</span>))
474
+
475
+ <span class="ruby-comment cmt"># load the project module</span>
476
+ <span class="ruby-identifier">require</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">join</span>(<span class="ruby-identifier">program_home</span>, <span class="ruby-value str">'lib'</span>, <span class="ruby-identifier">program_name</span>)
477
+ <span class="ruby-identifier">project_module</span> = <span class="ruby-identifier">fetch_project_module</span>(<span class="ruby-identifier">project_symbol</span>)
478
+
479
+ <span class="ruby-comment cmt"># parse command-line options</span>
480
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'trollop'</span>
481
+
482
+ <span class="ruby-identifier">options</span> = <span class="ruby-constant">Trollop</span>.<span class="ruby-identifier">options</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">trollop_args</span>) <span class="ruby-keyword kw">do</span>
483
+
484
+ <span class="ruby-comment cmt"># show project description</span>
485
+ <span class="ruby-identifier">text</span> <span class="ruby-node">&quot;#{project_module::PROJECT} - #{project_module::TAGLINE}&quot;</span>
486
+ <span class="ruby-identifier">text</span> <span class="ruby-value str">''</span>
487
+
488
+ <span class="ruby-comment cmt"># show program description</span>
489
+ <span class="ruby-identifier">text</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">read</span>(<span class="ruby-identifier">program_file</span>)[<span class="ruby-regexp re">/\A.*?^$\n/</span><span class="ruby-identifier">m</span>]. <span class="ruby-comment cmt"># grab the header</span>
490
+ <span class="ruby-identifier">gsub</span>(<span class="ruby-regexp re">/^# ?/</span>, <span class="ruby-value str">''</span>). <span class="ruby-comment cmt"># strip the comment markers</span>
491
+ <span class="ruby-identifier">sub</span>(<span class="ruby-regexp re">/\A!.*?\n/</span>, <span class="ruby-value str">''</span>).<span class="ruby-identifier">lstrip</span> <span class="ruby-comment cmt"># omit the shebang line</span>
492
+ <span class="ruby-identifier">text</span> <span class="ruby-value str">''</span>
493
+
494
+ <span class="ruby-identifier">instance_eval</span>(<span class="ruby-operator">&amp;</span><span class="ruby-identifier">trollop_config</span>) <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">trollop_config</span>
495
+
496
+ <span class="ruby-comment cmt"># show version information</span>
497
+ <span class="ruby-identifier">version</span> <span class="ruby-node">%w[PROJECT VERSION RELEASE WEBSITE INSTALL]</span>.<span class="ruby-identifier">map</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">c</span><span class="ruby-operator">|</span>
498
+ <span class="ruby-node">&quot;#{c.downcase}: #{project_module.const_get c}&quot;</span>
499
+ }.<span class="ruby-identifier">join</span>(<span class="ruby-value str">&quot;\n&quot;</span>)
500
+
501
+ <span class="ruby-identifier">opt</span> <span class="ruby-identifier">:manual</span>, <span class="ruby-value str">'Show the user manual'</span>
502
+ <span class="ruby-identifier">opt</span> <span class="ruby-identifier">:locale</span>, <span class="ruby-value str">'Set preferred language'</span>, <span class="ruby-identifier">:type</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">:string</span>
503
+ <span class="ruby-keyword kw">end</span>
504
+
505
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:manual</span>]
506
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'launchy'</span>
507
+
508
+ <span class="ruby-identifier">manual</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">join</span>(<span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">INSTALL</span>, <span class="ruby-value str">'doc'</span>, <span class="ruby-value str">'index.xhtml'</span>)
509
+ <span class="ruby-constant">Launchy</span><span class="ruby-operator">::</span><span class="ruby-constant">Browser</span>.<span class="ruby-identifier">run</span> <span class="ruby-identifier">manual</span>
510
+
511
+ <span class="ruby-identifier">exit</span>
512
+ <span class="ruby-keyword kw">end</span>
513
+
514
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">locale</span> = <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:locale</span>]
515
+ <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">PHRASES</span>.<span class="ruby-identifier">locale</span> = <span class="ruby-identifier">locale</span>
516
+ <span class="ruby-keyword kw">end</span>
517
+
518
+ <span class="ruby-identifier">options</span>
519
+ <span class="ruby-keyword kw">end</span></pre>
520
+ </div>
521
+ </div>
522
+
523
+ </div>
524
+
525
+ <div class="method">
526
+ <div class="title" id="M000014">
527
+
528
+ <a name="M000014"></a><b>rake</b>(project_symbol, options = {})
529
+
530
+ </div>
531
+
532
+ <div class="description">
533
+ <p>
534
+ Provides Rake tasks for packaging, publishing, and announcing your project.
535
+ </p>
536
+ <ul>
537
+ <li>An AUTHORS constant (which has the form &#8220;[[name, info]]&#8221; where
538
+ &#8220;name&#8221; is the name of a copyright holder and &#8220;info&#8221;
539
+ is their contact information) is added to the project module.
540
+
541
+ <p>
542
+ Unless this information is supplied via the :authors option, it is
543
+ automatically extracted from copyright notices in the project license file,
544
+ where the first copyright notice is expected to correspond to the primary
545
+ project maintainer.
546
+ </p>
547
+ <p>
548
+ Copyright notices must be in the following form:
549
+ </p>
550
+ <pre>
551
+ Copyright YEAR HOLDER &lt;EMAIL&gt;
552
+ </pre>
553
+ <p>
554
+ Where HOLDER is the name of the copyright holder, YEAR is the year when the
555
+ copyright holder first began working on the project, and EMAIL is
556
+ (optional) the email address of the copyright holder.
557
+ </p>
558
+ </li>
559
+ </ul>
560
+ <h4>Parameters</h4>
561
+ <dl>
562
+ <dt>project_symbol</dt><dd>Name of the Ruby constant which serves as a namespace for the entire
563
+ project.
564
+
565
+ </dd>
566
+ <dt>options</dt><dd>Optional hash of configuration parameters:
567
+
568
+ <dl>
569
+ <dt>:test_with</dt><dd>Names of Ruby libraries inside the &#8220;inochi/test/&#8220; namespace to
570
+ load before running the test suite.
571
+
572
+ <p>
573
+ The default value is an empty <a href="Array.html">Array</a>.
574
+ </p>
575
+ </dd>
576
+ <dt>:authors</dt><dd>A list of project authors and their contact information. This list must
577
+ have the form &#8220;[[name, info]]&#8221; where &#8220;name&#8221; is the
578
+ name of a project author and &#8220;info&#8221; is their contact
579
+ information.
580
+
581
+ <p>
582
+ The default value is automatically extracted from your project&#8217;s
583
+ license file (see description above).
584
+ </p>
585
+ </dd>
586
+ <dt>:license_file</dt><dd>Path (relative to the main project directory which contains the project
587
+ rakefile) to the file which contains the project license.
588
+
589
+ <p>
590
+ The default value is &#8220;LICENSE&#8221;.
591
+ </p>
592
+ </dd>
593
+ <dt>:logins_file</dt><dd>Path to the YAML file which contains login information for publishing
594
+ release announcements.
595
+
596
+ <p>
597
+ The default value is &#8220;~/.config/inochi/logins.yaml&#8220; where
598
+ &#8220;~&#8221; is the path to your home directory.
599
+ </p>
600
+ </dd>
601
+ <dt>:rubyforge_project</dt><dd>Name of the RubyForge project where release packages will be published.
602
+
603
+ <p>
604
+ The default value is the value of the PROGRAM constant.
605
+ </p>
606
+ </dd>
607
+ <dt>:rubyforge_section</dt><dd>Name of the RubyForge project&#8217;s <a href="File.html">File</a> Release
608
+ System section where release packages will be published.
609
+
610
+ <p>
611
+ The default value is the value of the :rubyforge_project parameter.
612
+ </p>
613
+ </dd>
614
+ <dt>:raa_project</dt><dd>Name of the RAA (Ruby Application Archive) entry for this project.
615
+
616
+ <p>
617
+ The default value is the value of the PROGRAM constant.
618
+ </p>
619
+ </dd>
620
+ <dt>:upload_target</dt><dd>Where to upload the project documentation. See &#8220;destination&#8221; in
621
+ the rsync manual.
622
+
623
+ <p>
624
+ The default value is nil.
625
+ </p>
626
+ </dd>
627
+ <dt>:upload_delete</dt><dd>Delete unknown files at the upload target location?
628
+
629
+ <p>
630
+ The default value is false.
631
+ </p>
632
+ </dd>
633
+ <dt>:upload_options</dt><dd><a href="Array.html">Array</a> of command-line arguments to the rsync
634
+ command.
635
+
636
+ <p>
637
+ The default value is an empty array.
638
+ </p>
639
+ </dd>
640
+ <dt>:inochi_consumer</dt><dd>Add <a href="Inochi.html">Inochi</a> as a runtime dependency to the created
641
+ gem?
642
+
643
+ <p>
644
+ The default value is true.
645
+ </p>
646
+ </dd>
647
+ <dt>:inochi_producer</dt><dd>Add <a href="Inochi.html">Inochi</a> as a development dependency to the
648
+ created gem?
649
+
650
+ <p>
651
+ The default value is true.
652
+ </p>
653
+ </dd>
654
+ </dl>
655
+ </dd>
656
+ <dt>gem_config</dt><dd>Optional block that is passed to Gem::specification.new() for additonal gem
657
+ configuration.
658
+
659
+ </dd>
660
+ </dl>
661
+
662
+ </div>
663
+
664
+
665
+
666
+
667
+ <div class="sourcecode">
668
+ <p class="source-link">
669
+ Source: <a href="javascript:toggleSource('M000014_source')" id="l_M000014_source">show</a>
670
+
671
+ | <a href="http://github.com/sunaku/inochi/blob/bb5ea888e45c928e0318cfbef999ce7f41994411/lib/inochi/rake.rb#L110" target="_blank" class="github_url">on GitHub</a>
672
+
673
+ </p>
674
+ <div id="M000014_source" class="dyn-source">
675
+ <pre><span class="ruby-comment cmt"># File lib/inochi/rake.rb, line 110</span>
676
+ <span class="ruby-keyword kw">def</span> <span class="ruby-constant">Inochi</span>.<span class="ruby-identifier">rake</span> <span class="ruby-identifier">project_symbol</span>, <span class="ruby-identifier">options</span> = {}, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">gem_config</span>
677
+ <span class="ruby-identifier">program_file</span> = <span class="ruby-identifier">first_caller_file</span>
678
+ <span class="ruby-identifier">program_home</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">dirname</span>(<span class="ruby-identifier">program_file</span>)
679
+
680
+ <span class="ruby-comment cmt"># load the project module</span>
681
+ <span class="ruby-identifier">program_name</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">basename</span>(<span class="ruby-identifier">program_home</span>)
682
+ <span class="ruby-identifier">project_libs</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">join</span>(<span class="ruby-value str">'lib'</span>, <span class="ruby-identifier">program_name</span>)
683
+
684
+ <span class="ruby-identifier">require</span> <span class="ruby-identifier">project_libs</span>
685
+ <span class="ruby-identifier">project_module</span> = <span class="ruby-identifier">fetch_project_module</span>(<span class="ruby-identifier">project_symbol</span>)
686
+
687
+ <span class="ruby-comment cmt"># supply default options</span>
688
+ <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:test_with</span>] <span class="ruby-operator">||=</span> []
689
+
690
+ <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:rubyforge_project</span>] <span class="ruby-operator">||=</span> <span class="ruby-identifier">program_name</span>
691
+ <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:rubyforge_section</span>] <span class="ruby-operator">||=</span> <span class="ruby-identifier">program_name</span>
692
+ <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:raa_project</span>] <span class="ruby-operator">||=</span> <span class="ruby-identifier">program_name</span>
693
+
694
+ <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:license_file</span>] <span class="ruby-operator">||=</span> <span class="ruby-value str">'LICENSE'</span>
695
+ <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:logins_file</span>] <span class="ruby-operator">||=</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">join</span>(
696
+ <span class="ruby-constant">ENV</span>[<span class="ruby-value str">'HOME'</span>] <span class="ruby-operator">||</span> <span class="ruby-constant">ENV</span>[<span class="ruby-value str">'USERPROFILE'</span>] <span class="ruby-operator">||</span> <span class="ruby-value str">'.'</span>,
697
+ <span class="ruby-value str">'.config'</span>, <span class="ruby-value str">'inochi'</span>, <span class="ruby-value str">'logins.yaml'</span>
698
+ )
699
+
700
+ <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:upload_options</span>] <span class="ruby-operator">||=</span> []
701
+
702
+ <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:inochi_consumer</span>] = <span class="ruby-keyword kw">true</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">key?</span> <span class="ruby-identifier">:inochi_consumer</span>
703
+ <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:inochi_producer</span>] = <span class="ruby-keyword kw">true</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">key?</span> <span class="ruby-identifier">:inochi_producer</span>
704
+
705
+ <span class="ruby-comment cmt"># add AUTHORS constant to the project module</span>
706
+ <span class="ruby-identifier">copyright_holders</span> = <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:authors</span>] <span class="ruby-operator">||</span>
707
+ <span class="ruby-constant">File</span>.<span class="ruby-identifier">read</span>(<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:license_file</span>]).
708
+ <span class="ruby-identifier">scan</span>(<span class="ruby-regexp re">/Copyright.*?\d+\s+(.*)/</span>).<span class="ruby-identifier">flatten</span>.
709
+ <span class="ruby-identifier">map</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">s</span><span class="ruby-operator">|</span> (<span class="ruby-identifier">s</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/\s*&lt;(.*?)&gt;/</span>) <span class="ruby-operator">?</span> [<span class="ruby-identifier">$`</span>, <span class="ruby-identifier">$1</span>] <span class="ruby-operator">:</span> [<span class="ruby-identifier">s</span>, <span class="ruby-value str">''</span>] }
710
+
711
+ <span class="ruby-identifier">project_module</span>.<span class="ruby-identifier">const_set</span> <span class="ruby-identifier">:AUTHORS</span>, <span class="ruby-identifier">copyright_holders</span>
712
+
713
+ <span class="ruby-comment cmt"># establish development gem dependencies</span>
714
+ [<span class="ruby-identifier">project_module</span>, <span class="ruby-constant">Inochi</span>].<span class="ruby-identifier">uniq</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">mod</span><span class="ruby-operator">|</span>
715
+ <span class="ruby-identifier">mod</span><span class="ruby-operator">::</span><span class="ruby-constant">DEVELOP</span>.<span class="ruby-identifier">each_pair</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">gem_name</span>, <span class="ruby-identifier">version_reqs</span><span class="ruby-operator">|</span>
716
+ <span class="ruby-identifier">require_gem_version</span> <span class="ruby-identifier">gem_name</span>, <span class="ruby-identifier">version_reqs</span>
717
+ <span class="ruby-keyword kw">end</span>
718
+ <span class="ruby-keyword kw">end</span>
719
+
720
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'rake/clean'</span>
721
+
722
+ <span class="ruby-identifier">hide_rake_task</span> = <span class="ruby-identifier">lambda</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">name</span><span class="ruby-operator">|</span>
723
+ <span class="ruby-constant">Rake</span><span class="ruby-operator">::</span><span class="ruby-constant">Task</span>[<span class="ruby-identifier">name</span>].<span class="ruby-identifier">instance_variable_set</span> <span class="ruby-identifier">:@comment</span>, <span class="ruby-keyword kw">nil</span>
724
+ <span class="ruby-keyword kw">end</span>
725
+
726
+ <span class="ruby-comment cmt"># translation</span>
727
+ <span class="ruby-identifier">directory</span> <span class="ruby-value str">'lang'</span>
728
+
729
+ <span class="ruby-identifier">lang_dump_deps</span> = <span class="ruby-value str">'lang'</span>
730
+ <span class="ruby-identifier">lang_dump_file</span> = <span class="ruby-value str">'lang/phrases.yaml'</span>
731
+
732
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Extract language phrases for translation.'</span>
733
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'lang:dump'</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">lang_dump_file</span>
734
+
735
+ <span class="ruby-identifier">file</span> <span class="ruby-identifier">lang_dump_file</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">lang_dump_deps</span> <span class="ruby-keyword kw">do</span>
736
+ <span class="ruby-constant">ENV</span>[<span class="ruby-value str">'dump_lang_phrases'</span>] = <span class="ruby-value str">'1'</span>
737
+ <span class="ruby-constant">Rake</span><span class="ruby-operator">::</span><span class="ruby-constant">Task</span>[<span class="ruby-identifier">:test</span>].<span class="ruby-identifier">invoke</span>
738
+ <span class="ruby-keyword kw">end</span>
739
+
740
+ <span class="ruby-identifier">lang_conv_delim</span> = <span class="ruby-value str">&quot;\n&quot;</span> <span class="ruby-operator">*</span> <span class="ruby-value">5</span>
741
+
742
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Translate extracted language phrases (from=LANGUAGE_CODE).'</span>
743
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'lang:conv'</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">lang_dump_file</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">t</span><span class="ruby-operator">|</span>
744
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'babelfish'</span>
745
+
746
+ <span class="ruby-keyword kw">unless</span>
747
+ <span class="ruby-identifier">src_lang</span> = <span class="ruby-constant">ENV</span>[<span class="ruby-value str">'from'</span>] <span class="ruby-keyword kw">and</span>
748
+ <span class="ruby-constant">BabelFish</span><span class="ruby-operator">::</span><span class="ruby-constant">LANGUAGE_CODES</span>.<span class="ruby-identifier">include?</span> <span class="ruby-identifier">src_lang</span>
749
+ <span class="ruby-keyword kw">then</span>
750
+ <span class="ruby-identifier">message</span> = [<span class="ruby-value str">'The &quot;from&quot; parameter must be specified as follows:'</span>]
751
+
752
+ <span class="ruby-constant">BabelFish</span><span class="ruby-operator">::</span><span class="ruby-constant">LANGUAGE_CODES</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">c</span><span class="ruby-operator">|</span>
753
+ <span class="ruby-identifier">n</span> = <span class="ruby-constant">BabelFish</span><span class="ruby-operator">::</span><span class="ruby-constant">LANGUAGE_NAMES</span>[<span class="ruby-identifier">c</span>]
754
+ <span class="ruby-identifier">message</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-node">&quot; rake #{t.name} from=#{c} # from #{n}&quot;</span>
755
+ <span class="ruby-keyword kw">end</span>
756
+
757
+ <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>, <span class="ruby-identifier">message</span>.<span class="ruby-identifier">join</span>(<span class="ruby-value str">&quot;\n&quot;</span>)
758
+ <span class="ruby-keyword kw">end</span>
759
+
760
+ <span class="ruby-keyword kw">begin</span>
761
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'yaml'</span>
762
+ <span class="ruby-identifier">phrases</span> = <span class="ruby-constant">YAML</span>.<span class="ruby-identifier">load_file</span>(<span class="ruby-identifier">lang_dump_file</span>).<span class="ruby-identifier">keys</span>.<span class="ruby-identifier">sort</span>
763
+ <span class="ruby-keyword kw">rescue</span>
764
+ <span class="ruby-identifier">warn</span> <span class="ruby-node">&quot;Could not load phrases from #{lang_dump_file.inspect}&quot;</span>
765
+ <span class="ruby-identifier">raise</span>
766
+ <span class="ruby-keyword kw">end</span>
767
+
768
+ <span class="ruby-identifier">src_lang_name</span> = <span class="ruby-constant">BabelFish</span><span class="ruby-operator">::</span><span class="ruby-constant">LANGUAGE_NAMES</span>[<span class="ruby-identifier">src_lang</span>]
769
+
770
+ <span class="ruby-constant">BabelFish</span><span class="ruby-operator">::</span><span class="ruby-constant">LANGUAGE_PAIRS</span>[<span class="ruby-identifier">src_lang</span>].<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">dst_lang</span><span class="ruby-operator">|</span>
771
+ <span class="ruby-identifier">dst_file</span> = <span class="ruby-node">&quot;lang/#{dst_lang}.yaml&quot;</span>
772
+ <span class="ruby-identifier">dst_lang_name</span> = <span class="ruby-constant">BabelFish</span><span class="ruby-operator">::</span><span class="ruby-constant">LANGUAGE_NAMES</span>[<span class="ruby-identifier">dst_lang</span>]
773
+
774
+ <span class="ruby-identifier">puts</span> <span class="ruby-node">&quot;Translating phrases from #{src_lang_name} into #{dst_lang_name} as #{dst_file.inspect}&quot;</span>
775
+
776
+ <span class="ruby-identifier">translations</span> = <span class="ruby-constant">BabelFish</span>.<span class="ruby-identifier">translate</span>(
777
+ <span class="ruby-identifier">phrases</span>.<span class="ruby-identifier">join</span>(<span class="ruby-identifier">lang_conv_delim</span>), <span class="ruby-identifier">src_lang</span>, <span class="ruby-identifier">dst_lang</span>
778
+ ).<span class="ruby-identifier">split</span>(<span class="ruby-identifier">lang_conv_delim</span>)
779
+
780
+ <span class="ruby-constant">File</span>.<span class="ruby-identifier">open</span>(<span class="ruby-identifier">dst_file</span>, <span class="ruby-value str">'w'</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">f</span><span class="ruby-operator">|</span>
781
+ <span class="ruby-identifier">f</span>.<span class="ruby-identifier">puts</span> <span class="ruby-node">&quot;# #{dst_lang} (#{dst_lang_name})&quot;</span>
782
+
783
+ <span class="ruby-identifier">phrases</span>.<span class="ruby-identifier">zip</span>(<span class="ruby-identifier">translations</span>).<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">a</span>, <span class="ruby-identifier">b</span><span class="ruby-operator">|</span>
784
+ <span class="ruby-identifier">f</span>.<span class="ruby-identifier">puts</span> <span class="ruby-node">&quot;#{a}: #{b}&quot;</span>
785
+ <span class="ruby-keyword kw">end</span>
786
+ <span class="ruby-keyword kw">end</span>
787
+ <span class="ruby-keyword kw">end</span>
788
+ <span class="ruby-keyword kw">end</span>
789
+
790
+ <span class="ruby-comment cmt"># testing</span>
791
+ <span class="ruby-identifier">test_runner</span> = <span class="ruby-identifier">lambda</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">interpreter</span><span class="ruby-operator">|</span>
792
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'tempfile'</span>
793
+ <span class="ruby-identifier">script</span> = <span class="ruby-constant">Tempfile</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">$$</span>).<span class="ruby-identifier">path</span> <span class="ruby-comment cmt"># will be deleted on program exit</span>
794
+
795
+ <span class="ruby-identifier">libs</span> = [<span class="ruby-identifier">program_name</span>] <span class="ruby-operator">+</span> <span class="ruby-comment cmt"># load the project-under-test's library FIRST!</span>
796
+ <span class="ruby-constant">Array</span>(<span class="ruby-identifier">options</span>[<span class="ruby-identifier">:test_with</span>]).<span class="ruby-identifier">map</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">lib</span><span class="ruby-operator">|</span> <span class="ruby-node">&quot;inochi/test/#{lib}&quot;</span> }
797
+
798
+ <span class="ruby-constant">File</span>.<span class="ruby-identifier">write</span> <span class="ruby-identifier">script</span>, <span class="ruby-node">%{
799
+ # the &quot;-I.&quot; option lets us load helper libraries inside
800
+ # the test suite via &quot;test/PROJECT_NAME/LIBRARY_NAME&quot;
801
+ $LOAD_PATH.unshift '.', 'lib'
802
+
803
+ #{libs.inspect}.each do |lib|
804
+ require lib
805
+ end
806
+
807
+ # set title of test suite
808
+ $0 = #{project_module.to_s.inspect}
809
+
810
+ # dump language phrases *after* exercising all code (and
811
+ # thereby populating the phrases cache) in the project
812
+ at_exit do
813
+ if ENV['dump_lang_phrases'] == '1'
814
+ file = #{File.expand_path(lang_dump_file).inspect}
815
+ list = eval(#{project_symbol.to_s.inspect})::PHRASES.phrases
816
+ data = list.map {|s| s + ':' }.join(&quot;\n&quot;)
817
+
818
+ File.write file, data
819
+
820
+ puts &quot;Extracted \#{list.length} language phrases into \#{file.inspect}&quot;
821
+ end
822
+ end
823
+
824
+ Dir['test/**/*.rb'].sort.each do |test|
825
+ unit = test.sub('test/', 'lib/')
826
+
827
+ if File.exist? unit
828
+ # strip file extension because require()
829
+ # does not normalize its input and it
830
+ # will think that the two paths (with &amp;
831
+ # without file extension) are different
832
+ unit_path = unit.sub(/\.rb$/, '').sub('lib/', '')
833
+ test_path = test.sub(/\.rb$/, '')
834
+
835
+ require unit_path
836
+ require test_path
837
+ else
838
+ warn &quot;Skipped test \#{test.inspect} because it lacks a corresponding \#{unit.inspect} unit.&quot;
839
+ end
840
+ end
841
+ }</span>
842
+
843
+ <span class="ruby-identifier">command</span> = [<span class="ruby-identifier">interpreter</span>.<span class="ruby-identifier">to_s</span>]
844
+
845
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">interpreter</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">:rcov</span>
846
+ <span class="ruby-identifier">command</span>.<span class="ruby-identifier">push</span> <span class="ruby-value str">'--output'</span>, <span class="ruby-value str">'cov'</span>
847
+
848
+ <span class="ruby-comment cmt"># omit internals from coverage analysis</span>
849
+ <span class="ruby-identifier">command</span>.<span class="ruby-identifier">push</span> <span class="ruby-value str">'--exclude-only'</span>, <span class="ruby-identifier">script</span>
850
+ <span class="ruby-identifier">command</span>.<span class="ruby-identifier">push</span> <span class="ruby-value str">'--exclude'</span>, <span class="ruby-constant">Inochi</span><span class="ruby-operator">::</span><span class="ruby-constant">INSTALL</span>
851
+
852
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'rbconfig'</span>
853
+ <span class="ruby-identifier">ruby_internals</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">dirname</span>(<span class="ruby-constant">Config</span><span class="ruby-operator">::</span><span class="ruby-constant">CONFIG</span>[<span class="ruby-value str">'rubylibdir'</span>])
854
+ <span class="ruby-identifier">command</span>.<span class="ruby-identifier">push</span> <span class="ruby-value str">'--exclude'</span>, <span class="ruby-node">/^#{Regexp.quote ruby_internals}/</span>.<span class="ruby-identifier">to_s</span>
855
+
856
+ <span class="ruby-comment cmt"># show results summary after execution</span>
857
+ <span class="ruby-identifier">command</span>.<span class="ruby-identifier">push</span> <span class="ruby-value str">'-T'</span>
858
+ <span class="ruby-keyword kw">else</span>
859
+ <span class="ruby-comment cmt"># enable Ruby warnings during execution</span>
860
+ <span class="ruby-identifier">command</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-value str">'-w'</span>
861
+ <span class="ruby-keyword kw">end</span>
862
+
863
+ <span class="ruby-identifier">command</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">script</span>
864
+
865
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'shellwords'</span>
866
+ <span class="ruby-identifier">command</span>.<span class="ruby-identifier">concat</span> <span class="ruby-constant">Shellwords</span>.<span class="ruby-identifier">shellwords</span>(<span class="ruby-constant">ENV</span>[<span class="ruby-value str">'opts'</span>].<span class="ruby-identifier">to_s</span>)
867
+
868
+ <span class="ruby-identifier">sh</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">command</span>)
869
+ <span class="ruby-keyword kw">end</span>
870
+
871
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Run tests.'</span>
872
+ <span class="ruby-identifier">task</span> <span class="ruby-identifier">:test</span> <span class="ruby-keyword kw">do</span>
873
+ <span class="ruby-identifier">test_runner</span>.<span class="ruby-identifier">call</span> <span class="ruby-identifier">:ruby</span>
874
+ <span class="ruby-keyword kw">end</span>
875
+
876
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Run tests with code coverage analysis.'</span>
877
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'test:cov'</span> <span class="ruby-keyword kw">do</span>
878
+ <span class="ruby-identifier">test_runner</span>.<span class="ruby-identifier">call</span> <span class="ruby-identifier">:rcov</span>
879
+ <span class="ruby-keyword kw">end</span>
880
+
881
+ <span class="ruby-constant">CLEAN</span>.<span class="ruby-identifier">include</span> <span class="ruby-value str">'cov'</span>
882
+
883
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Run tests with multiple Ruby versions.'</span>
884
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'test:ruby'</span> <span class="ruby-keyword kw">do</span>
885
+ <span class="ruby-identifier">test_runner</span>.<span class="ruby-identifier">call</span> <span class="ruby-identifier">:multiruby</span>
886
+ <span class="ruby-keyword kw">end</span>
887
+
888
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Report code quality statistics.'</span>
889
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'lint'</span> <span class="ruby-keyword kw">do</span>
890
+ <span class="ruby-identifier">separator</span> = <span class="ruby-value str">'-'</span> <span class="ruby-operator">*</span> <span class="ruby-value">80</span>
891
+
892
+ <span class="ruby-identifier">linter</span> = <span class="ruby-identifier">lambda</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-operator">*</span><span class="ruby-identifier">command</span><span class="ruby-operator">|</span>
893
+ <span class="ruby-identifier">name</span> = <span class="ruby-identifier">command</span>.<span class="ruby-identifier">first</span>
894
+
895
+ <span class="ruby-identifier">puts</span> <span class="ruby-value str">&quot;\n\n&quot;</span>, <span class="ruby-identifier">separator</span>, <span class="ruby-identifier">name</span>, <span class="ruby-identifier">separator</span>
896
+ <span class="ruby-identifier">system</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">command</span>)
897
+ <span class="ruby-keyword kw">end</span>
898
+
899
+ <span class="ruby-identifier">ruby_files</span> = <span class="ruby-constant">Dir</span>[<span class="ruby-value str">'**/*.rb'</span>]
900
+
901
+ <span class="ruby-identifier">linter</span>.<span class="ruby-identifier">call</span> <span class="ruby-value str">'sloccount'</span>, <span class="ruby-value str">'.'</span>
902
+ <span class="ruby-identifier">linter</span>.<span class="ruby-identifier">call</span> <span class="ruby-value str">'flay'</span> <span class="ruby-comment cmt"># operates on all .rb &amp; .erb files by default</span>
903
+ <span class="ruby-identifier">linter</span>.<span class="ruby-identifier">call</span> <span class="ruby-value str">'reek'</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">ruby_files</span>
904
+ <span class="ruby-identifier">linter</span>.<span class="ruby-identifier">call</span> <span class="ruby-value str">'roodi'</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">ruby_files</span>
905
+ <span class="ruby-keyword kw">end</span>
906
+
907
+ <span class="ruby-comment cmt"># documentation</span>
908
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Build all documentation.'</span>
909
+ <span class="ruby-identifier">task</span> <span class="ruby-identifier">:doc</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-node">%w[ doc:api doc:man ]</span>
910
+
911
+ <span class="ruby-comment cmt"># user manual</span>
912
+ <span class="ruby-identifier">doc_man_src</span> = <span class="ruby-value str">'doc/index.erb'</span>
913
+ <span class="ruby-identifier">doc_man_dst</span> = <span class="ruby-value str">'doc/index.xhtml'</span>
914
+ <span class="ruby-identifier">doc_man_deps</span> = <span class="ruby-constant">FileList</span>[<span class="ruby-value str">'doc/*.erb'</span>]
915
+
916
+ <span class="ruby-identifier">doc_man_doc</span> = <span class="ruby-keyword kw">nil</span>
917
+ <span class="ruby-identifier">task</span> <span class="ruby-identifier">:doc_man_doc</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">doc_man_src</span> <span class="ruby-keyword kw">do</span>
918
+ <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">doc_man_doc</span>
919
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'erbook'</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-keyword kw">defined?</span> <span class="ruby-constant">ERBook</span>
920
+
921
+ <span class="ruby-identifier">doc_man_txt</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">read</span>(<span class="ruby-identifier">doc_man_src</span>)
922
+ <span class="ruby-identifier">doc_man_doc</span> = <span class="ruby-constant">ERBook</span><span class="ruby-operator">::</span><span class="ruby-constant">Document</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">:xhtml</span>, <span class="ruby-identifier">doc_man_txt</span>, <span class="ruby-identifier">doc_man_src</span>, <span class="ruby-identifier">:unindent</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-keyword kw">true</span>)
923
+ <span class="ruby-keyword kw">end</span>
924
+ <span class="ruby-keyword kw">end</span>
925
+
926
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Build the user manual.'</span>
927
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'doc:man'</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">doc_man_dst</span>
928
+
929
+ <span class="ruby-identifier">file</span> <span class="ruby-identifier">doc_man_dst</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">doc_man_deps</span> <span class="ruby-keyword kw">do</span>
930
+ <span class="ruby-constant">Rake</span><span class="ruby-operator">::</span><span class="ruby-constant">Task</span>[<span class="ruby-identifier">:doc_man_doc</span>].<span class="ruby-identifier">invoke</span>
931
+ <span class="ruby-constant">File</span>.<span class="ruby-identifier">write</span> <span class="ruby-identifier">doc_man_dst</span>, <span class="ruby-identifier">doc_man_doc</span>
932
+ <span class="ruby-keyword kw">end</span>
933
+
934
+ <span class="ruby-constant">CLOBBER</span>.<span class="ruby-identifier">include</span> <span class="ruby-identifier">doc_man_dst</span>
935
+
936
+ <span class="ruby-comment cmt"># API reference</span>
937
+ <span class="ruby-identifier">doc_api_dst</span> = <span class="ruby-value str">'doc/api'</span>
938
+
939
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Build API reference.'</span>
940
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'doc:api'</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value str">'doc:api:rdoc'</span>
941
+
942
+ <span class="ruby-identifier">namespace</span> <span class="ruby-identifier">:doc</span> <span class="ruby-keyword kw">do</span>
943
+ <span class="ruby-identifier">namespace</span> <span class="ruby-identifier">:api</span> <span class="ruby-keyword kw">do</span>
944
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'sdoc'</span>
945
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'rake/rdoctask'</span>
946
+
947
+ <span class="ruby-constant">Rake</span><span class="ruby-operator">::</span><span class="ruby-constant">RDocTask</span>.<span class="ruby-identifier">new</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">t</span><span class="ruby-operator">|</span>
948
+ <span class="ruby-identifier">t</span>.<span class="ruby-identifier">rdoc_dir</span> = <span class="ruby-identifier">doc_api_dst</span>
949
+ <span class="ruby-identifier">t</span>.<span class="ruby-identifier">template</span> = <span class="ruby-value str">'direct'</span> <span class="ruby-comment cmt"># lighter template used on railsapi.com</span>
950
+ <span class="ruby-identifier">t</span>.<span class="ruby-identifier">options</span>.<span class="ruby-identifier">push</span> <span class="ruby-value str">'--fmt'</span>, <span class="ruby-value str">'shtml'</span> <span class="ruby-comment cmt"># explictly set shtml generator</span>
951
+ <span class="ruby-identifier">t</span>.<span class="ruby-identifier">rdoc_files</span>.<span class="ruby-identifier">include</span> <span class="ruby-value str">'[A-Z]*'</span>, <span class="ruby-value str">'lib/**/*.rb'</span>, <span class="ruby-value str">'ext/**/*.{rb,c*}'</span>
952
+
953
+ <span class="ruby-comment cmt"># regen when sources change</span>
954
+ <span class="ruby-identifier">task</span> <span class="ruby-identifier">t</span>.<span class="ruby-identifier">name</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">t</span>.<span class="ruby-identifier">rdoc_files</span>
955
+
956
+ <span class="ruby-identifier">t</span>.<span class="ruby-identifier">main</span> = <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:license_file</span>]
957
+ <span class="ruby-identifier">task</span> <span class="ruby-identifier">t</span>.<span class="ruby-identifier">name</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">t</span>.<span class="ruby-identifier">main</span>
958
+ <span class="ruby-keyword kw">end</span>
959
+
960
+ <span class="ruby-node">%w[rdoc clobber_rdoc rerdoc]</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">inner</span><span class="ruby-operator">|</span>
961
+ <span class="ruby-identifier">hide_rake_task</span>[<span class="ruby-node">&quot;doc:api:#{inner}&quot;</span>]
962
+ <span class="ruby-keyword kw">end</span>
963
+ <span class="ruby-keyword kw">end</span>
964
+ <span class="ruby-keyword kw">end</span>
965
+
966
+ <span class="ruby-constant">CLOBBER</span>.<span class="ruby-identifier">include</span> <span class="ruby-identifier">doc_api_dst</span>
967
+
968
+ <span class="ruby-comment cmt"># announcements</span>
969
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Build all release announcements.'</span>
970
+ <span class="ruby-identifier">task</span> <span class="ruby-identifier">:ann</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-node">%w[ ann:feed ann:html ann:text ann:mail ]</span>
971
+
972
+ <span class="ruby-comment cmt"># it has long been a tradition to use an &quot;[ANN]&quot; prefix</span>
973
+ <span class="ruby-comment cmt"># when announcing things on the ruby-talk mailing list</span>
974
+ <span class="ruby-identifier">ann_prefix</span> = <span class="ruby-value str">'[ANN] '</span>
975
+ <span class="ruby-identifier">ann_subject</span> = <span class="ruby-identifier">ann_prefix</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">DISPLAY</span>
976
+ <span class="ruby-identifier">ann_project</span> = <span class="ruby-identifier">ann_prefix</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">PROJECT</span>
977
+
978
+ <span class="ruby-comment cmt"># fetch the project summary from user manual</span>
979
+ <span class="ruby-identifier">ann_nfo_doc</span> = <span class="ruby-keyword kw">nil</span>
980
+ <span class="ruby-identifier">task</span> <span class="ruby-identifier">:ann_nfo_doc</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">:doc_man_doc</span> <span class="ruby-keyword kw">do</span>
981
+ <span class="ruby-identifier">ann_nfo_doc</span> = <span class="ruby-identifier">$project_summary_node</span>
982
+ <span class="ruby-keyword kw">end</span>
983
+
984
+ <span class="ruby-comment cmt"># fetch release notes from user manual</span>
985
+ <span class="ruby-identifier">ann_rel_doc</span> = <span class="ruby-keyword kw">nil</span>
986
+ <span class="ruby-identifier">task</span> <span class="ruby-identifier">:ann_rel_doc</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">:doc_man_doc</span> <span class="ruby-keyword kw">do</span>
987
+ <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">ann_rel_doc</span>
988
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">parent</span> = <span class="ruby-identifier">$project_history_node</span>
989
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">child</span> = <span class="ruby-identifier">parent</span>.<span class="ruby-identifier">children</span>.<span class="ruby-identifier">first</span>
990
+ <span class="ruby-identifier">ann_rel_doc</span> = <span class="ruby-identifier">child</span>
991
+ <span class="ruby-keyword kw">else</span>
992
+ <span class="ruby-identifier">raise</span> <span class="ruby-value str">'The &quot;project_history&quot; node in the user manual lacks child nodes.'</span>
993
+ <span class="ruby-keyword kw">end</span>
994
+ <span class="ruby-keyword kw">else</span>
995
+ <span class="ruby-identifier">raise</span> <span class="ruby-value str">'The user manual lacks a &quot;project_history&quot; node.'</span>
996
+ <span class="ruby-keyword kw">end</span>
997
+ <span class="ruby-keyword kw">end</span>
998
+ <span class="ruby-keyword kw">end</span>
999
+
1000
+ <span class="ruby-comment cmt"># build release notes in HTML and plain text</span>
1001
+ <span class="ruby-comment cmt"># converts the given HTML into plain text. we do this using</span>
1002
+ <span class="ruby-comment cmt"># lynx because (1) it outputs a list of all hyperlinks used</span>
1003
+ <span class="ruby-comment cmt"># in the HTML document and (2) it runs on all major platforms</span>
1004
+ <span class="ruby-identifier">convert_html_to_text</span> = <span class="ruby-identifier">lambda</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">html</span><span class="ruby-operator">|</span>
1005
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'tempfile'</span>
1006
+
1007
+ <span class="ruby-keyword kw">begin</span>
1008
+ <span class="ruby-comment cmt"># lynx's -dump option requires a .html file</span>
1009
+ <span class="ruby-identifier">tmp_file</span> = <span class="ruby-constant">Tempfile</span>.<span class="ruby-identifier">new</span>(<span class="ruby-constant">Inochi</span><span class="ruby-operator">::</span><span class="ruby-constant">PROGRAM</span>).<span class="ruby-identifier">path</span> <span class="ruby-operator">+</span> <span class="ruby-value str">'.html'</span>
1010
+
1011
+ <span class="ruby-constant">File</span>.<span class="ruby-identifier">write</span> <span class="ruby-identifier">tmp_file</span>, <span class="ruby-identifier">html</span>
1012
+ <span class="ruby-identifier">text</span> = <span class="ruby-node">`lynx -dump #{tmp_file} -width 70`</span>
1013
+ <span class="ruby-keyword kw">ensure</span>
1014
+ <span class="ruby-constant">File</span>.<span class="ruby-identifier">delete</span> <span class="ruby-identifier">tmp_file</span>
1015
+ <span class="ruby-keyword kw">end</span>
1016
+
1017
+ <span class="ruby-comment cmt"># improve readability of list items</span>
1018
+ <span class="ruby-comment cmt"># by adding a blank line between them</span>
1019
+ <span class="ruby-identifier">text</span>.<span class="ruby-identifier">gsub!</span> <span class="ruby-regexp re">%r{(\r?\n)( +\* \S)}</span>, <span class="ruby-value str">'\1\1\2'</span>
1020
+
1021
+ <span class="ruby-identifier">text</span>
1022
+ <span class="ruby-keyword kw">end</span>
1023
+
1024
+ <span class="ruby-comment cmt"># binds relative addresses in the given HTML to the project docsite</span>
1025
+ <span class="ruby-identifier">resolve_html_links</span> = <span class="ruby-identifier">lambda</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">html</span><span class="ruby-operator">|</span>
1026
+ <span class="ruby-comment cmt"># resolve relative URLs into absolute URLs</span>
1027
+ <span class="ruby-comment cmt"># see http://en.wikipedia.org/wiki/URI_scheme#Generic_syntax</span>
1028
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'addressable/uri'</span>
1029
+ <span class="ruby-identifier">uri</span> = <span class="ruby-constant">Addressable</span><span class="ruby-operator">::</span><span class="ruby-constant">URI</span>.<span class="ruby-identifier">parse</span>(<span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">DOCSITE</span>)
1030
+ <span class="ruby-identifier">doc_url</span> = <span class="ruby-identifier">uri</span>.<span class="ruby-identifier">to_s</span>
1031
+ <span class="ruby-identifier">dir_url</span> = <span class="ruby-identifier">uri</span>.<span class="ruby-identifier">path</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">%r{/$|^$}</span> <span class="ruby-operator">?</span> <span class="ruby-identifier">doc_url</span> <span class="ruby-operator">:</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">dirname</span>(<span class="ruby-identifier">doc_url</span>)
1032
+
1033
+ <span class="ruby-identifier">html</span>.<span class="ruby-identifier">to_s</span>.<span class="ruby-identifier">gsub</span> <span class="ruby-regexp re">%r{(href=|src=)(.)(.*?)(\2)}</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">match</span><span class="ruby-operator">|</span>
1034
+ <span class="ruby-identifier">a</span>, <span class="ruby-identifier">b</span> = <span class="ruby-identifier">$1</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">$2</span>, <span class="ruby-identifier">$3</span>.<span class="ruby-identifier">to_s</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">$4</span>
1035
+
1036
+ <span class="ruby-keyword kw">case</span> <span class="ruby-identifier">$3</span>
1037
+ <span class="ruby-keyword kw">when</span> <span class="ruby-regexp re">%r{^[[:alpha:]][[:alnum:]\+\.\-]*://}</span> <span class="ruby-comment cmt"># already absolute</span>
1038
+ <span class="ruby-identifier">match</span>
1039
+
1040
+ <span class="ruby-keyword kw">when</span> <span class="ruby-regexp re">/^#/</span>
1041
+ <span class="ruby-identifier">a</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">join</span>(<span class="ruby-identifier">doc_url</span>, <span class="ruby-identifier">b</span>)
1042
+
1043
+ <span class="ruby-keyword kw">else</span>
1044
+ <span class="ruby-identifier">a</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">join</span>(<span class="ruby-identifier">dir_url</span>, <span class="ruby-identifier">b</span>)
1045
+ <span class="ruby-keyword kw">end</span>
1046
+ <span class="ruby-keyword kw">end</span>
1047
+ <span class="ruby-keyword kw">end</span>
1048
+
1049
+ <span class="ruby-identifier">ann_html</span> = <span class="ruby-keyword kw">nil</span>
1050
+ <span class="ruby-identifier">task</span> <span class="ruby-identifier">:ann_html</span> =<span class="ruby-operator">&gt;</span> [<span class="ruby-identifier">:doc_man_doc</span>, <span class="ruby-identifier">:ann_nfo_doc</span>, <span class="ruby-identifier">:ann_rel_doc</span>] <span class="ruby-keyword kw">do</span>
1051
+ <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">ann_html</span>
1052
+ <span class="ruby-identifier">ann_html</span> = <span class="ruby-node">%{
1053
+ &lt;center&gt;
1054
+ &lt;h1&gt;#{project_module::DISPLAY}&lt;/h1&gt;
1055
+ &lt;p&gt;#{project_module::TAGLINE}&lt;/p&gt;
1056
+ &lt;p&gt;#{project_module::WEBSITE}&lt;/p&gt;
1057
+ &lt;/center&gt;
1058
+ #{ann_nfo_doc}
1059
+ #{ann_rel_doc}
1060
+ }</span>
1061
+
1062
+ <span class="ruby-comment cmt"># remove heading navigation menus</span>
1063
+ <span class="ruby-identifier">ann_html</span>.<span class="ruby-identifier">gsub!</span> <span class="ruby-regexp re">%r{&lt;div class=&quot;nav&quot;[^&gt;]*&gt;(.*?)&lt;/div&gt;}</span>, <span class="ruby-value str">''</span>
1064
+
1065
+ <span class="ruby-comment cmt"># remove latex-style heading numbers</span>
1066
+ <span class="ruby-identifier">ann_html</span>.<span class="ruby-identifier">gsub!</span> <span class="ruby-regexp re">%r&quot;(&lt;(h\d)[^&gt;]*&gt;).+?(?:&amp;nbsp;){2}(.+?)(&lt;/\2&gt;)&quot;</span><span class="ruby-identifier">m</span>, <span class="ruby-value str">'\1\3\4'</span>
1067
+
1068
+ <span class="ruby-identifier">ann_html</span> = <span class="ruby-identifier">resolve_html_links</span>[<span class="ruby-identifier">ann_html</span>]
1069
+ <span class="ruby-keyword kw">end</span>
1070
+ <span class="ruby-keyword kw">end</span>
1071
+
1072
+ <span class="ruby-identifier">ann_text</span> = <span class="ruby-keyword kw">nil</span>
1073
+ <span class="ruby-identifier">task</span> <span class="ruby-identifier">:ann_text</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">:ann_html</span> <span class="ruby-keyword kw">do</span>
1074
+ <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">ann_text</span>
1075
+ <span class="ruby-identifier">ann_text</span> = <span class="ruby-identifier">convert_html_to_text</span>[<span class="ruby-identifier">ann_html</span>]
1076
+ <span class="ruby-keyword kw">end</span>
1077
+ <span class="ruby-keyword kw">end</span>
1078
+
1079
+ <span class="ruby-identifier">ann_nfo_text</span> = <span class="ruby-keyword kw">nil</span>
1080
+ <span class="ruby-identifier">task</span> <span class="ruby-identifier">:ann_nfo_text</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">:ann_nfo_doc</span> <span class="ruby-keyword kw">do</span>
1081
+ <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">ann_nfo_text</span>
1082
+ <span class="ruby-identifier">ann_nfo_html</span> = <span class="ruby-identifier">resolve_html_links</span>[<span class="ruby-identifier">ann_nfo_doc</span>]
1083
+ <span class="ruby-identifier">ann_nfo_text</span> = <span class="ruby-identifier">convert_html_to_text</span>[<span class="ruby-identifier">ann_nfo_html</span>]
1084
+ <span class="ruby-keyword kw">end</span>
1085
+ <span class="ruby-keyword kw">end</span>
1086
+
1087
+ <span class="ruby-comment cmt"># HTML</span>
1088
+ <span class="ruby-identifier">ann_html_dst</span> = <span class="ruby-value str">'ANN.html'</span>
1089
+
1090
+ <span class="ruby-identifier">desc</span> <span class="ruby-node">&quot;Build HTML announcement: #{ann_html_dst}&quot;</span>
1091
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'ann:html'</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">ann_html_dst</span>
1092
+
1093
+ <span class="ruby-identifier">file</span> <span class="ruby-identifier">ann_html_dst</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">doc_man_deps</span> <span class="ruby-keyword kw">do</span>
1094
+ <span class="ruby-constant">Rake</span><span class="ruby-operator">::</span><span class="ruby-constant">Task</span>[<span class="ruby-identifier">:ann_html</span>].<span class="ruby-identifier">invoke</span>
1095
+ <span class="ruby-constant">File</span>.<span class="ruby-identifier">write</span> <span class="ruby-identifier">ann_html_dst</span>, <span class="ruby-identifier">ann_html</span>
1096
+ <span class="ruby-keyword kw">end</span>
1097
+
1098
+ <span class="ruby-constant">CLEAN</span>.<span class="ruby-identifier">include</span> <span class="ruby-identifier">ann_html_dst</span>
1099
+
1100
+ <span class="ruby-comment cmt"># RSS feed</span>
1101
+ <span class="ruby-identifier">ann_feed_dst</span> = <span class="ruby-value str">'doc/ann.xml'</span>
1102
+
1103
+ <span class="ruby-identifier">desc</span> <span class="ruby-node">&quot;Build RSS announcement: #{ann_feed_dst}&quot;</span>
1104
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'ann:feed'</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">ann_feed_dst</span>
1105
+
1106
+ <span class="ruby-identifier">file</span> <span class="ruby-identifier">ann_feed_dst</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">doc_man_deps</span> <span class="ruby-keyword kw">do</span>
1107
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'time'</span>
1108
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'rss/maker'</span>
1109
+
1110
+ <span class="ruby-identifier">feed</span> = <span class="ruby-constant">RSS</span><span class="ruby-operator">::</span><span class="ruby-constant">Maker</span>.<span class="ruby-identifier">make</span>(<span class="ruby-value str">'2.0'</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">feed</span><span class="ruby-operator">|</span>
1111
+ <span class="ruby-identifier">feed</span>.<span class="ruby-identifier">channel</span>.<span class="ruby-identifier">title</span> = <span class="ruby-identifier">ann_project</span>
1112
+ <span class="ruby-identifier">feed</span>.<span class="ruby-identifier">channel</span>.<span class="ruby-identifier">link</span> = <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">WEBSITE</span>
1113
+ <span class="ruby-identifier">feed</span>.<span class="ruby-identifier">channel</span>.<span class="ruby-identifier">description</span> = <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">TAGLINE</span>
1114
+
1115
+ <span class="ruby-constant">Rake</span><span class="ruby-operator">::</span><span class="ruby-constant">Task</span>[<span class="ruby-identifier">:ann_rel_doc</span>].<span class="ruby-identifier">invoke</span>
1116
+ <span class="ruby-constant">Rake</span><span class="ruby-operator">::</span><span class="ruby-constant">Task</span>[<span class="ruby-identifier">:ann_html</span>].<span class="ruby-identifier">invoke</span>
1117
+
1118
+ <span class="ruby-identifier">item</span> = <span class="ruby-identifier">feed</span>.<span class="ruby-identifier">items</span>.<span class="ruby-identifier">new_item</span>
1119
+ <span class="ruby-identifier">item</span>.<span class="ruby-identifier">title</span> = <span class="ruby-identifier">ann_rel_doc</span>.<span class="ruby-identifier">title</span>
1120
+ <span class="ruby-identifier">item</span>.<span class="ruby-identifier">link</span> = <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">DOCSITE</span> <span class="ruby-operator">+</span> <span class="ruby-value str">'#'</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">ann_rel_doc</span>.<span class="ruby-identifier">here_frag</span>
1121
+ <span class="ruby-identifier">item</span>.<span class="ruby-identifier">date</span> = <span class="ruby-constant">Time</span>.<span class="ruby-identifier">parse</span>(<span class="ruby-identifier">item</span>.<span class="ruby-identifier">title</span>)
1122
+ <span class="ruby-identifier">item</span>.<span class="ruby-identifier">description</span> = <span class="ruby-identifier">ann_html</span>
1123
+ <span class="ruby-keyword kw">end</span>
1124
+
1125
+ <span class="ruby-constant">File</span>.<span class="ruby-identifier">write</span> <span class="ruby-identifier">ann_feed_dst</span>, <span class="ruby-identifier">feed</span>
1126
+ <span class="ruby-keyword kw">end</span>
1127
+
1128
+ <span class="ruby-constant">CLOBBER</span>.<span class="ruby-identifier">include</span> <span class="ruby-identifier">ann_feed_dst</span>
1129
+
1130
+ <span class="ruby-comment cmt"># plain text</span>
1131
+ <span class="ruby-identifier">ann_text_dst</span> = <span class="ruby-value str">'ANN.txt'</span>
1132
+
1133
+ <span class="ruby-identifier">desc</span> <span class="ruby-node">&quot;Build plain text announcement: #{ann_text_dst}&quot;</span>
1134
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'ann:text'</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">ann_text_dst</span>
1135
+
1136
+ <span class="ruby-identifier">file</span> <span class="ruby-identifier">ann_text_dst</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">doc_man_deps</span> <span class="ruby-keyword kw">do</span>
1137
+ <span class="ruby-constant">Rake</span><span class="ruby-operator">::</span><span class="ruby-constant">Task</span>[<span class="ruby-identifier">:ann_text</span>].<span class="ruby-identifier">invoke</span>
1138
+ <span class="ruby-constant">File</span>.<span class="ruby-identifier">write</span> <span class="ruby-identifier">ann_text_dst</span>, <span class="ruby-identifier">ann_text</span>
1139
+ <span class="ruby-keyword kw">end</span>
1140
+
1141
+ <span class="ruby-constant">CLEAN</span>.<span class="ruby-identifier">include</span> <span class="ruby-identifier">ann_text_dst</span>
1142
+
1143
+ <span class="ruby-comment cmt"># e-mail</span>
1144
+ <span class="ruby-identifier">ann_mail_dst</span> = <span class="ruby-value str">'ANN.eml'</span>
1145
+
1146
+ <span class="ruby-identifier">desc</span> <span class="ruby-node">&quot;Build e-mail announcement: #{ann_mail_dst}&quot;</span>
1147
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'ann:mail'</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">ann_mail_dst</span>
1148
+
1149
+ <span class="ruby-identifier">file</span> <span class="ruby-identifier">ann_mail_dst</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">doc_man_deps</span> <span class="ruby-keyword kw">do</span>
1150
+ <span class="ruby-constant">File</span>.<span class="ruby-identifier">open</span> <span class="ruby-identifier">ann_mail_dst</span>, <span class="ruby-value str">'w'</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">f</span><span class="ruby-operator">|</span>
1151
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'time'</span>
1152
+ <span class="ruby-identifier">f</span>.<span class="ruby-identifier">puts</span> <span class="ruby-node">&quot;Date: #{Time.now.rfc822}&quot;</span>
1153
+
1154
+ <span class="ruby-identifier">f</span>.<span class="ruby-identifier">puts</span> <span class="ruby-value str">'To: ruby-talk@ruby-lang.org'</span>
1155
+ <span class="ruby-identifier">f</span>.<span class="ruby-identifier">puts</span> <span class="ruby-value str">'From: &quot;%s&quot; &lt;%s&gt;'</span> <span class="ruby-operator">%</span> <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">AUTHORS</span>.<span class="ruby-identifier">first</span>
1156
+ <span class="ruby-identifier">f</span>.<span class="ruby-identifier">puts</span> <span class="ruby-node">&quot;Subject: #{ann_subject}&quot;</span>
1157
+
1158
+ <span class="ruby-constant">Rake</span><span class="ruby-operator">::</span><span class="ruby-constant">Task</span>[<span class="ruby-identifier">:ann_text</span>].<span class="ruby-identifier">invoke</span>
1159
+ <span class="ruby-identifier">f</span>.<span class="ruby-identifier">puts</span> <span class="ruby-value str">''</span>, <span class="ruby-identifier">ann_text</span>
1160
+ <span class="ruby-keyword kw">end</span>
1161
+ <span class="ruby-keyword kw">end</span>
1162
+
1163
+ <span class="ruby-constant">CLEAN</span>.<span class="ruby-identifier">include</span> <span class="ruby-identifier">ann_mail_dst</span>
1164
+
1165
+ <span class="ruby-comment cmt"># packaging</span>
1166
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Build a release.'</span>
1167
+ <span class="ruby-identifier">task</span> <span class="ruby-identifier">:gem</span> =<span class="ruby-operator">&gt;</span> [<span class="ruby-identifier">:clobber</span>, <span class="ruby-identifier">:doc</span>] <span class="ruby-keyword kw">do</span>
1168
+ <span class="ruby-identifier">sh</span> <span class="ruby-identifier">$0</span>, <span class="ruby-value str">'gem:package'</span>
1169
+ <span class="ruby-keyword kw">end</span>
1170
+ <span class="ruby-constant">CLEAN</span>.<span class="ruby-identifier">include</span> <span class="ruby-value str">'pkg'</span>
1171
+
1172
+ <span class="ruby-comment cmt"># ruby gem</span>
1173
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'rake/gempackagetask'</span>
1174
+
1175
+ <span class="ruby-identifier">gem_spec</span> = <span class="ruby-constant">Gem</span><span class="ruby-operator">::</span><span class="ruby-constant">Specification</span>.<span class="ruby-identifier">new</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">gem</span><span class="ruby-operator">|</span>
1176
+ <span class="ruby-identifier">authors</span> = <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">AUTHORS</span>
1177
+
1178
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">author</span> = <span class="ruby-identifier">authors</span>.<span class="ruby-identifier">first</span>
1179
+ <span class="ruby-identifier">gem</span>.<span class="ruby-identifier">author</span>, <span class="ruby-identifier">gem</span>.<span class="ruby-identifier">email</span> = <span class="ruby-identifier">author</span>
1180
+ <span class="ruby-keyword kw">end</span>
1181
+
1182
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">authors</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">&gt;</span> <span class="ruby-value">1</span>
1183
+ <span class="ruby-identifier">gem</span>.<span class="ruby-identifier">authors</span> = <span class="ruby-identifier">authors</span>.<span class="ruby-identifier">map</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">name</span>, <span class="ruby-identifier">mail</span><span class="ruby-operator">|</span> <span class="ruby-identifier">name</span> }
1184
+ <span class="ruby-keyword kw">end</span>
1185
+
1186
+ <span class="ruby-identifier">gem</span>.<span class="ruby-identifier">rubyforge_project</span> = <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:rubyforge_project</span>]
1187
+
1188
+ <span class="ruby-comment cmt"># XXX: In theory, `gem.name` should be assigned to</span>
1189
+ <span class="ruby-comment cmt"># ::PROJECT instead of ::PROGRAM</span>
1190
+ <span class="ruby-comment cmt">#</span>
1191
+ <span class="ruby-comment cmt"># In practice, PROJECT may contain non-word</span>
1192
+ <span class="ruby-comment cmt"># characters and may also contain a mixture</span>
1193
+ <span class="ruby-comment cmt"># of lowercase and uppercase letters.</span>
1194
+ <span class="ruby-comment cmt">#</span>
1195
+ <span class="ruby-comment cmt"># This makes it difficult for people to</span>
1196
+ <span class="ruby-comment cmt"># install the project gem because they must</span>
1197
+ <span class="ruby-comment cmt"># remember the exact spelling used in</span>
1198
+ <span class="ruby-comment cmt"># `gem.name` when running `gem install ____`.</span>
1199
+ <span class="ruby-comment cmt">#</span>
1200
+ <span class="ruby-comment cmt"># For example, consider the &quot;RedCloth&quot; gem.</span>
1201
+ <span class="ruby-comment cmt">#</span>
1202
+ <span class="ruby-identifier">gem</span>.<span class="ruby-identifier">name</span> = <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">PROGRAM</span>
1203
+
1204
+ <span class="ruby-identifier">gem</span>.<span class="ruby-identifier">version</span> = <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">VERSION</span>
1205
+ <span class="ruby-identifier">gem</span>.<span class="ruby-identifier">summary</span> = <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">TAGLINE</span>
1206
+ <span class="ruby-identifier">gem</span>.<span class="ruby-identifier">description</span> = <span class="ruby-identifier">gem</span>.<span class="ruby-identifier">summary</span>
1207
+ <span class="ruby-identifier">gem</span>.<span class="ruby-identifier">homepage</span> = <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">WEBSITE</span>
1208
+ <span class="ruby-identifier">gem</span>.<span class="ruby-identifier">files</span> = <span class="ruby-constant">FileList</span>[<span class="ruby-value str">'**/*'</span>].<span class="ruby-identifier">exclude</span>(<span class="ruby-value str">'_darcs'</span>) <span class="ruby-operator">-</span> <span class="ruby-constant">CLEAN</span>
1209
+ <span class="ruby-identifier">gem</span>.<span class="ruby-identifier">has_rdoc</span> = <span class="ruby-keyword kw">true</span>
1210
+
1211
+ <span class="ruby-identifier">executable</span> = <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">PROGRAM</span>
1212
+ <span class="ruby-identifier">executable_path</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">join</span>(<span class="ruby-identifier">gem</span>.<span class="ruby-identifier">bindir</span>, <span class="ruby-identifier">executable</span>)
1213
+ <span class="ruby-identifier">gem</span>.<span class="ruby-identifier">executables</span> = <span class="ruby-identifier">executable</span> <span class="ruby-keyword kw">if</span> <span class="ruby-constant">File</span>.<span class="ruby-identifier">exist?</span> <span class="ruby-identifier">executable_path</span>
1214
+
1215
+ <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">DEVELOP</span>.<span class="ruby-identifier">each_pair</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">gem_name</span>, <span class="ruby-identifier">version_reqs</span><span class="ruby-operator">|</span>
1216
+ <span class="ruby-identifier">version_reqs</span> = <span class="ruby-constant">Array</span>(<span class="ruby-identifier">version_reqs</span>).<span class="ruby-identifier">compact</span>
1217
+ <span class="ruby-identifier">gem</span>.<span class="ruby-identifier">add_development_dependency</span> <span class="ruby-identifier">gem_name</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">version_reqs</span>
1218
+ <span class="ruby-keyword kw">end</span>
1219
+
1220
+ <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">REQUIRE</span>.<span class="ruby-identifier">each_pair</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">gem_name</span>, <span class="ruby-identifier">version_reqs</span><span class="ruby-operator">|</span>
1221
+ <span class="ruby-identifier">version_reqs</span> = <span class="ruby-constant">Array</span>(<span class="ruby-identifier">version_reqs</span>).<span class="ruby-identifier">compact</span>
1222
+ <span class="ruby-identifier">gem</span>.<span class="ruby-identifier">add_dependency</span> <span class="ruby-identifier">gem_name</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">version_reqs</span>
1223
+ <span class="ruby-keyword kw">end</span>
1224
+
1225
+ <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">project_module</span> <span class="ruby-operator">==</span> <span class="ruby-constant">Inochi</span>
1226
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:inochi_producer</span>]
1227
+ <span class="ruby-identifier">gem</span>.<span class="ruby-identifier">add_development_dependency</span> <span class="ruby-constant">Inochi</span><span class="ruby-operator">::</span><span class="ruby-constant">PROGRAM</span>, <span class="ruby-constant">Inochi</span><span class="ruby-operator">::</span><span class="ruby-constant">VERSION</span>.<span class="ruby-identifier">requirement</span>
1228
+ <span class="ruby-keyword kw">end</span>
1229
+
1230
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:inochi_consumer</span>]
1231
+ <span class="ruby-identifier">gem</span>.<span class="ruby-identifier">add_dependency</span> <span class="ruby-constant">Inochi</span><span class="ruby-operator">::</span><span class="ruby-constant">PROGRAM</span>, <span class="ruby-constant">Inochi</span><span class="ruby-operator">::</span><span class="ruby-constant">VERSION</span>.<span class="ruby-identifier">requirement</span>
1232
+ <span class="ruby-keyword kw">end</span>
1233
+ <span class="ruby-keyword kw">end</span>
1234
+
1235
+ <span class="ruby-comment cmt"># additional configuration is done by user</span>
1236
+ <span class="ruby-keyword kw">yield</span> <span class="ruby-identifier">gem</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">gem_config</span>
1237
+ <span class="ruby-keyword kw">end</span>
1238
+
1239
+ <span class="ruby-identifier">namespace</span> <span class="ruby-identifier">:gem</span> <span class="ruby-keyword kw">do</span>
1240
+ <span class="ruby-constant">Rake</span><span class="ruby-operator">::</span><span class="ruby-constant">GemPackageTask</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">gem_spec</span>).<span class="ruby-identifier">define</span>
1241
+
1242
+ <span class="ruby-node">%w[gem package repackage clobber_package]</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">t</span><span class="ruby-operator">|</span>
1243
+ <span class="ruby-identifier">hide_rake_task</span>.<span class="ruby-identifier">call</span> <span class="ruby-node">&quot;gem:#{t}&quot;</span>
1244
+ <span class="ruby-keyword kw">end</span>
1245
+ <span class="ruby-keyword kw">end</span>
1246
+
1247
+ <span class="ruby-identifier">task</span> <span class="ruby-identifier">:clobber</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value str">&quot;gem:clobber_package&quot;</span>
1248
+
1249
+ <span class="ruby-comment cmt"># releasing</span>
1250
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Publish a release.'</span>
1251
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'pub'</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-node">%w[ pub:gem pub:doc pub:ann ]</span>
1252
+
1253
+ <span class="ruby-comment cmt"># connect to RubyForge services</span>
1254
+ <span class="ruby-identifier">pub_forge</span> = <span class="ruby-keyword kw">nil</span>
1255
+ <span class="ruby-identifier">pub_forge_project</span> = <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:rubyforge_project</span>]
1256
+ <span class="ruby-identifier">pub_forge_section</span> = <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:rubyforge_section</span>]
1257
+
1258
+ <span class="ruby-identifier">task</span> <span class="ruby-identifier">:pub_forge</span> <span class="ruby-keyword kw">do</span>
1259
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'rubyforge'</span>
1260
+ <span class="ruby-identifier">pub_forge</span> = <span class="ruby-constant">RubyForge</span>.<span class="ruby-identifier">new</span>
1261
+ <span class="ruby-identifier">pub_forge</span>.<span class="ruby-identifier">configure</span>(<span class="ruby-value str">'release_date'</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">RELEASE</span>)
1262
+
1263
+ <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">pub_forge</span>.<span class="ruby-identifier">autoconfig</span>[<span class="ruby-value str">'group_ids'</span>].<span class="ruby-identifier">key?</span> <span class="ruby-identifier">pub_forge_project</span>
1264
+ <span class="ruby-identifier">raise</span> <span class="ruby-node">&quot;The #{pub_forge_project.inspect} project was not recognized by the RubyForge client. Either specify a different RubyForge project by passing the :rubyforge_project option to Inochi.rake(), or ensure that the client is configured correctly (see `rubyforge --help` for help) and try again.&quot;</span>
1265
+ <span class="ruby-keyword kw">end</span>
1266
+
1267
+ <span class="ruby-identifier">pub_forge</span>.<span class="ruby-identifier">login</span>
1268
+ <span class="ruby-keyword kw">end</span>
1269
+
1270
+ <span class="ruby-comment cmt"># documentation</span>
1271
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Publish documentation to project website.'</span>
1272
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'pub:doc'</span> =<span class="ruby-operator">&gt;</span> [<span class="ruby-identifier">:doc</span>, <span class="ruby-value str">'ann:feed'</span>] <span class="ruby-keyword kw">do</span>
1273
+ <span class="ruby-identifier">target</span> = <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:upload_target</span>]
1274
+
1275
+ <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">target</span>
1276
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'addressable/uri'</span>
1277
+ <span class="ruby-identifier">docsite</span> = <span class="ruby-constant">Addressable</span><span class="ruby-operator">::</span><span class="ruby-constant">URI</span>.<span class="ruby-identifier">parse</span>(<span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">DOCSITE</span>)
1278
+
1279
+ <span class="ruby-comment cmt"># provide uploading capability to websites hosted on RubyForge</span>
1280
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">docsite</span>.<span class="ruby-identifier">host</span>.<span class="ruby-identifier">include?</span> <span class="ruby-value str">'.rubyforge.org'</span>
1281
+ <span class="ruby-identifier">target</span> = <span class="ruby-node">&quot;#{pub_forge.userconfig['username']}@rubyforge.org:#{File.join '/var/www/gforge-projects', options[:rubyforge_project], docsite.path}&quot;</span>
1282
+ <span class="ruby-keyword kw">end</span>
1283
+ <span class="ruby-keyword kw">end</span>
1284
+
1285
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">target</span>
1286
+ <span class="ruby-identifier">cmd</span> = [<span class="ruby-value str">'rsync'</span>, <span class="ruby-value str">'-auvz'</span>, <span class="ruby-value str">'doc/'</span>, <span class="ruby-node">&quot;#{target}/&quot;</span>]
1287
+ <span class="ruby-identifier">cmd</span>.<span class="ruby-identifier">push</span> <span class="ruby-value str">'--delete'</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:upload_delete</span>]
1288
+ <span class="ruby-identifier">cmd</span>.<span class="ruby-identifier">concat</span> <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:upload_options</span>]
1289
+
1290
+ <span class="ruby-identifier">p</span> <span class="ruby-identifier">cmd</span>
1291
+ <span class="ruby-identifier">sh</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">cmd</span>)
1292
+ <span class="ruby-keyword kw">end</span>
1293
+ <span class="ruby-keyword kw">end</span>
1294
+
1295
+ <span class="ruby-comment cmt"># announcement</span>
1296
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Publish all announcements.'</span>
1297
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'pub:ann'</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-node">%w[ pub:ann:forge pub:ann:raa pub:ann:talk ]</span>
1298
+
1299
+ <span class="ruby-comment cmt"># login information</span>
1300
+ <span class="ruby-identifier">ann_logins_file</span> = <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:logins_file</span>]
1301
+ <span class="ruby-identifier">ann_logins</span> = <span class="ruby-keyword kw">nil</span>
1302
+
1303
+ <span class="ruby-identifier">task</span> <span class="ruby-identifier">:ann_logins</span> <span class="ruby-keyword kw">do</span>
1304
+ <span class="ruby-identifier">ann_logins</span> = <span class="ruby-keyword kw">begin</span>
1305
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'yaml'</span>
1306
+ <span class="ruby-constant">YAML</span>.<span class="ruby-identifier">load_file</span> <span class="ruby-identifier">ann_logins_file</span>
1307
+ <span class="ruby-keyword kw">rescue</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">e</span>
1308
+ <span class="ruby-identifier">warn</span> <span class="ruby-node">&quot;Could not read login information from #{ann_logins_file.inspect}:&quot;</span>
1309
+ <span class="ruby-identifier">warn</span> <span class="ruby-identifier">e</span>
1310
+ <span class="ruby-identifier">warn</span> <span class="ruby-value str">&quot;** You will NOT be able to publish release announcements! **&quot;</span>
1311
+ {}
1312
+ <span class="ruby-keyword kw">end</span>
1313
+ <span class="ruby-keyword kw">end</span>
1314
+
1315
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Announce to RubyForge news.'</span>
1316
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'pub:ann:forge'</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">:pub_forge</span> <span class="ruby-keyword kw">do</span>
1317
+ <span class="ruby-identifier">puts</span> <span class="ruby-value str">'Announcing to RubyForge news...'</span>
1318
+
1319
+ <span class="ruby-identifier">project</span> = <span class="ruby-identifier">options</span>[<span class="ruby-identifier">:rubyforge_project</span>]
1320
+
1321
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">group_id</span> = <span class="ruby-identifier">pub_forge</span>.<span class="ruby-identifier">autoconfig</span>[<span class="ruby-value str">'group_ids'</span>][<span class="ruby-identifier">project</span>]
1322
+ <span class="ruby-comment cmt"># check if this release was already announced</span>
1323
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'mechanize'</span>
1324
+ <span class="ruby-identifier">www</span> = <span class="ruby-constant">WWW</span><span class="ruby-operator">::</span><span class="ruby-constant">Mechanize</span>.<span class="ruby-identifier">new</span>
1325
+ <span class="ruby-identifier">page</span> = <span class="ruby-identifier">www</span>.<span class="ruby-identifier">get</span> <span class="ruby-node">&quot;http://rubyforge.org/news/?group_id=#{group_id}&quot;</span>
1326
+
1327
+ <span class="ruby-identifier">posts</span> = (<span class="ruby-identifier">page</span><span class="ruby-operator">/</span><span class="ruby-value str">'//a[starts-with(./@href, &quot;/forum/forum.php?forum_id=&quot;)]/text()'</span>).<span class="ruby-identifier">map</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">e</span><span class="ruby-operator">|</span> <span class="ruby-identifier">e</span>.<span class="ruby-identifier">to_s</span>.<span class="ruby-identifier">gsub</span>(<span class="ruby-value str">&quot;\302\240&quot;</span>, <span class="ruby-value str">''</span>).<span class="ruby-identifier">strip</span> }
1328
+
1329
+ <span class="ruby-identifier">already_announced</span> = <span class="ruby-identifier">posts</span>.<span class="ruby-identifier">include?</span> <span class="ruby-identifier">ann_subject</span>
1330
+
1331
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">already_announced</span>
1332
+ <span class="ruby-identifier">warn</span> <span class="ruby-value str">'This release was already announced to RubyForge news, so I will NOT announce it there again.'</span>
1333
+ <span class="ruby-keyword kw">else</span>
1334
+ <span class="ruby-comment cmt"># make the announcement</span>
1335
+ <span class="ruby-constant">Rake</span><span class="ruby-operator">::</span><span class="ruby-constant">Task</span>[<span class="ruby-identifier">:ann_text</span>].<span class="ruby-identifier">invoke</span>
1336
+ <span class="ruby-identifier">pub_forge</span>.<span class="ruby-identifier">post_news</span> <span class="ruby-identifier">project</span>, <span class="ruby-identifier">ann_subject</span>, <span class="ruby-identifier">ann_text</span>
1337
+
1338
+ <span class="ruby-identifier">puts</span> <span class="ruby-value str">'Successfully announced to RubyForge news:'</span>, <span class="ruby-identifier">page</span>.<span class="ruby-identifier">uri</span>
1339
+ <span class="ruby-keyword kw">end</span>
1340
+ <span class="ruby-keyword kw">else</span>
1341
+ <span class="ruby-identifier">raise</span> <span class="ruby-node">&quot;Could not determine the group_id of the #{project.inspect} RubyForge project. Run `rubyforge config` and try again.&quot;</span>
1342
+ <span class="ruby-keyword kw">end</span>
1343
+ <span class="ruby-keyword kw">end</span>
1344
+
1345
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Announce to ruby-talk mailing list.'</span>
1346
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'pub:ann:talk'</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">:ann_logins</span> <span class="ruby-keyword kw">do</span>
1347
+ <span class="ruby-identifier">puts</span> <span class="ruby-value str">'Announcing to ruby-talk mailing list...'</span>
1348
+
1349
+ <span class="ruby-identifier">host</span> = <span class="ruby-value str">'http://ruby-forum.com'</span>
1350
+ <span class="ruby-identifier">ruby_talk</span> = <span class="ruby-value">4</span> <span class="ruby-comment cmt"># ruby-talk forum ID</span>
1351
+
1352
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'mechanize'</span>
1353
+ <span class="ruby-identifier">www</span> = <span class="ruby-constant">WWW</span><span class="ruby-operator">::</span><span class="ruby-constant">Mechanize</span>.<span class="ruby-identifier">new</span>
1354
+
1355
+ <span class="ruby-comment cmt"># check if this release was already announced</span>
1356
+ <span class="ruby-identifier">already_announced</span> =
1357
+ <span class="ruby-keyword kw">begin</span>
1358
+ <span class="ruby-identifier">page</span> = <span class="ruby-identifier">www</span>.<span class="ruby-identifier">get</span> <span class="ruby-node">&quot;#{host}/forum/#{ruby_talk}&quot;</span>, <span class="ruby-identifier">:filter</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-node">%{&quot;#{ann_subject}&quot;}</span>
1359
+
1360
+ <span class="ruby-identifier">posts</span> = (<span class="ruby-identifier">page</span><span class="ruby-operator">/</span><span class="ruby-value str">'//div[@class=&quot;forum&quot;]//a[starts-with(./@href, &quot;/topic/&quot;)]/text()'</span>).<span class="ruby-identifier">map</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">e</span><span class="ruby-operator">|</span> <span class="ruby-identifier">e</span>.<span class="ruby-identifier">to_s</span>.<span class="ruby-identifier">strip</span> }
1361
+ <span class="ruby-identifier">posts</span>.<span class="ruby-identifier">include?</span> <span class="ruby-identifier">ann_subject</span>
1362
+ <span class="ruby-keyword kw">rescue</span>
1363
+ <span class="ruby-keyword kw">false</span>
1364
+ <span class="ruby-keyword kw">end</span>
1365
+
1366
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">already_announced</span>
1367
+ <span class="ruby-identifier">warn</span> <span class="ruby-value str">'This release was already announced to the ruby-talk mailing list, so I will NOT announce it there again.'</span>
1368
+ <span class="ruby-keyword kw">else</span>
1369
+ <span class="ruby-comment cmt"># log in to RubyForum</span>
1370
+ <span class="ruby-identifier">page</span> = <span class="ruby-identifier">www</span>.<span class="ruby-identifier">get</span> <span class="ruby-node">&quot;#{host}/user/login&quot;</span>
1371
+ <span class="ruby-identifier">form</span> = <span class="ruby-identifier">page</span>.<span class="ruby-identifier">forms</span>.<span class="ruby-identifier">first</span>
1372
+
1373
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">login</span> = <span class="ruby-identifier">ann_logins</span>[<span class="ruby-value str">'www.ruby-forum.com'</span>]
1374
+ <span class="ruby-identifier">form</span>[<span class="ruby-value str">'name'</span>] = <span class="ruby-identifier">login</span>[<span class="ruby-value str">'user'</span>]
1375
+ <span class="ruby-identifier">form</span>[<span class="ruby-value str">'password'</span>] = <span class="ruby-identifier">login</span>[<span class="ruby-value str">'pass'</span>]
1376
+ <span class="ruby-keyword kw">end</span>
1377
+
1378
+ <span class="ruby-identifier">page</span> = <span class="ruby-identifier">form</span>.<span class="ruby-identifier">click_button</span> <span class="ruby-comment cmt"># use the first submit button</span>
1379
+
1380
+ <span class="ruby-keyword kw">if</span> (<span class="ruby-identifier">page</span><span class="ruby-operator">/</span><span class="ruby-value str">'//a[@href=&quot;/user/logout&quot;]'</span>).<span class="ruby-identifier">empty?</span>
1381
+ <span class="ruby-identifier">warn</span> <span class="ruby-node">&quot;Could not log in to RubyForum using the login information in #{ann_logins_file.inspect}, so I can NOT announce this release to the ruby-talk mailing list.&quot;</span>
1382
+ <span class="ruby-keyword kw">else</span>
1383
+ <span class="ruby-comment cmt"># make the announcement</span>
1384
+ <span class="ruby-identifier">page</span> = <span class="ruby-identifier">www</span>.<span class="ruby-identifier">get</span> <span class="ruby-node">&quot;#{host}/topic/new?forum_id=#{ruby_talk}&quot;</span>
1385
+ <span class="ruby-identifier">form</span> = <span class="ruby-identifier">page</span>.<span class="ruby-identifier">forms</span>.<span class="ruby-identifier">first</span>
1386
+
1387
+ <span class="ruby-constant">Rake</span><span class="ruby-operator">::</span><span class="ruby-constant">Task</span>[<span class="ruby-identifier">:ann_text</span>].<span class="ruby-identifier">invoke</span>
1388
+ <span class="ruby-identifier">form</span>[<span class="ruby-value str">'post[subject]'</span>] = <span class="ruby-identifier">ann_subject</span>
1389
+ <span class="ruby-identifier">form</span>[<span class="ruby-value str">'post[text]'</span>] = <span class="ruby-identifier">ann_text</span>
1390
+
1391
+ <span class="ruby-comment cmt"># enable email notification</span>
1392
+ <span class="ruby-identifier">form</span>.<span class="ruby-identifier">field_with</span>(<span class="ruby-identifier">:name</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-value str">'post[subscribed_by_author]'</span>).<span class="ruby-identifier">value</span> = <span class="ruby-value str">'1'</span>
1393
+
1394
+ <span class="ruby-identifier">page</span> = <span class="ruby-identifier">form</span>.<span class="ruby-identifier">submit</span>
1395
+ <span class="ruby-identifier">errors</span> = <span class="ruby-constant">Array</span>(<span class="ruby-identifier">page</span><span class="ruby-operator">/</span><span class="ruby-value str">'//div[@class=&quot;error&quot;]/text()'</span>)
1396
+
1397
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">errors</span>.<span class="ruby-identifier">empty?</span>
1398
+ <span class="ruby-identifier">puts</span> <span class="ruby-value str">'Successfully announced to ruby-talk mailing list:'</span>, <span class="ruby-identifier">page</span>.<span class="ruby-identifier">uri</span>
1399
+ <span class="ruby-keyword kw">else</span>
1400
+ <span class="ruby-identifier">warn</span> <span class="ruby-value str">'Could not announce to ruby-talk mailing list:'</span>
1401
+ <span class="ruby-identifier">warn</span> <span class="ruby-identifier">errors</span>.<span class="ruby-identifier">join</span>(<span class="ruby-value str">&quot;\n&quot;</span>)
1402
+ <span class="ruby-keyword kw">end</span>
1403
+ <span class="ruby-keyword kw">end</span>
1404
+ <span class="ruby-keyword kw">end</span>
1405
+ <span class="ruby-keyword kw">end</span>
1406
+
1407
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Announce to RAA (Ruby Application Archive).'</span>
1408
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'pub:ann:raa'</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">:ann_logins</span> <span class="ruby-keyword kw">do</span>
1409
+ <span class="ruby-identifier">puts</span> <span class="ruby-value str">'Announcing to RAA (Ruby Application Archive)...'</span>
1410
+
1411
+ <span class="ruby-identifier">show_page_error</span> = <span class="ruby-identifier">lambda</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">page</span>, <span class="ruby-identifier">message</span><span class="ruby-operator">|</span>
1412
+ <span class="ruby-identifier">warn</span> <span class="ruby-node">&quot;#{message}, so I can NOT announce this release to RAA:&quot;</span>
1413
+ <span class="ruby-identifier">warn</span> <span class="ruby-node">&quot;#{(page/'h2').text} -- #{(page/'p').first.text.strip}&quot;</span>
1414
+ <span class="ruby-keyword kw">end</span>
1415
+
1416
+ <span class="ruby-identifier">resource</span> = <span class="ruby-node">&quot;#{options[:raa_project].inspect} project entry on RAA&quot;</span>
1417
+
1418
+ <span class="ruby-identifier">require</span> <span class="ruby-value str">'mechanize'</span>
1419
+ <span class="ruby-identifier">www</span> = <span class="ruby-constant">WWW</span><span class="ruby-operator">::</span><span class="ruby-constant">Mechanize</span>.<span class="ruby-identifier">new</span>
1420
+ <span class="ruby-identifier">page</span> = <span class="ruby-identifier">www</span>.<span class="ruby-identifier">get</span> <span class="ruby-node">&quot;http://raa.ruby-lang.org/update.rhtml?name=#{options[:raa_project]}&quot;</span>
1421
+
1422
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">form</span> = <span class="ruby-identifier">page</span>.<span class="ruby-identifier">forms</span>[<span class="ruby-value">1</span>]
1423
+ <span class="ruby-identifier">resource</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-node">&quot; (owned by #{form.owner.inspect})&quot;</span>
1424
+
1425
+ <span class="ruby-constant">Rake</span><span class="ruby-operator">::</span><span class="ruby-constant">Task</span>[<span class="ruby-identifier">:ann_nfo_text</span>].<span class="ruby-identifier">invoke</span>
1426
+ <span class="ruby-identifier">form</span>[<span class="ruby-value str">'description'</span>] = <span class="ruby-identifier">ann_nfo_text</span>
1427
+ <span class="ruby-identifier">form</span>[<span class="ruby-value str">'description_style'</span>] = <span class="ruby-value str">'Pre-formatted'</span>
1428
+ <span class="ruby-identifier">form</span>[<span class="ruby-value str">'short_description'</span>] = <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">TAGLINE</span>
1429
+ <span class="ruby-identifier">form</span>[<span class="ruby-value str">'version'</span>] = <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">VERSION</span>
1430
+ <span class="ruby-identifier">form</span>[<span class="ruby-value str">'url'</span>] = <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">WEBSITE</span>
1431
+ <span class="ruby-identifier">form</span>[<span class="ruby-value str">'pass'</span>] = <span class="ruby-identifier">ann_logins</span>[<span class="ruby-value str">'raa.ruby-lang.org'</span>][<span class="ruby-value str">'pass'</span>]
1432
+
1433
+ <span class="ruby-identifier">page</span> = <span class="ruby-identifier">form</span>.<span class="ruby-identifier">submit</span>
1434
+
1435
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">page</span>.<span class="ruby-identifier">title</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/error/i</span>
1436
+ <span class="ruby-identifier">show_page_error</span>[<span class="ruby-identifier">page</span>, <span class="ruby-node">&quot;Could not update #{resource}&quot;</span>]
1437
+ <span class="ruby-keyword kw">else</span>
1438
+ <span class="ruby-identifier">puts</span> <span class="ruby-value str">'Successfully announced to RAA (Ruby Application Archive).'</span>
1439
+ <span class="ruby-keyword kw">end</span>
1440
+ <span class="ruby-keyword kw">else</span>
1441
+ <span class="ruby-identifier">show_page_error</span>[<span class="ruby-identifier">page</span>, <span class="ruby-node">&quot;Could not access #{resource}&quot;</span>]
1442
+ <span class="ruby-keyword kw">end</span>
1443
+ <span class="ruby-keyword kw">end</span>
1444
+
1445
+ <span class="ruby-comment cmt"># release packages</span>
1446
+ <span class="ruby-identifier">desc</span> <span class="ruby-value str">'Publish release packages to RubyForge.'</span>
1447
+ <span class="ruby-identifier">task</span> <span class="ruby-value str">'pub:gem'</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">:pub_forge</span> <span class="ruby-keyword kw">do</span>
1448
+ <span class="ruby-comment cmt"># check if this release was already published</span>
1449
+ <span class="ruby-identifier">version</span> = <span class="ruby-identifier">project_module</span><span class="ruby-operator">::</span><span class="ruby-constant">VERSION</span>
1450
+ <span class="ruby-identifier">packages</span> = <span class="ruby-identifier">pub_forge</span>.<span class="ruby-identifier">autoconfig</span>[<span class="ruby-value str">'release_ids'</span>][<span class="ruby-identifier">pub_forge_section</span>]
1451
+
1452
+ <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">packages</span> <span class="ruby-keyword kw">and</span> <span class="ruby-identifier">packages</span>.<span class="ruby-identifier">key?</span> <span class="ruby-identifier">version</span>
1453
+ <span class="ruby-identifier">warn</span> <span class="ruby-value str">&quot;The release packages were already published, so I will NOT publish them again.&quot;</span>
1454
+ <span class="ruby-keyword kw">else</span>
1455
+ <span class="ruby-comment cmt"># create the FRS package section</span>
1456
+ <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">pub_forge</span>.<span class="ruby-identifier">autoconfig</span>[<span class="ruby-value str">'package_ids'</span>].<span class="ruby-identifier">key?</span> <span class="ruby-identifier">pub_forge_section</span>
1457
+ <span class="ruby-identifier">pub_forge</span>.<span class="ruby-identifier">create_package</span> <span class="ruby-identifier">pub_forge_project</span>, <span class="ruby-identifier">pub_forge_section</span>
1458
+ <span class="ruby-keyword kw">end</span>
1459
+
1460
+ <span class="ruby-comment cmt"># publish the package to the section</span>
1461
+ <span class="ruby-identifier">uploader</span> = <span class="ruby-identifier">lambda</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">command</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">files</span><span class="ruby-operator">|</span>
1462
+ <span class="ruby-identifier">pub_forge</span>.<span class="ruby-identifier">__send__</span> <span class="ruby-identifier">command</span>, <span class="ruby-identifier">pub_forge_project</span>, <span class="ruby-identifier">pub_forge_section</span>, <span class="ruby-identifier">version</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">files</span>
1463
+ <span class="ruby-keyword kw">end</span>
1464
+
1465
+ <span class="ruby-constant">Rake</span><span class="ruby-operator">::</span><span class="ruby-constant">Task</span>[<span class="ruby-identifier">:gem</span>].<span class="ruby-identifier">invoke</span>
1466
+ <span class="ruby-identifier">packages</span> = <span class="ruby-constant">Dir</span>[<span class="ruby-value str">'pkg/*.[a-z]*'</span>]
1467
+
1468
+ <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">packages</span>.<span class="ruby-identifier">empty?</span>
1469
+ <span class="ruby-comment cmt"># NOTE: use the 'add_release' command ONLY for the first</span>
1470
+ <span class="ruby-comment cmt"># file because it creates a new sub-section on the</span>
1471
+ <span class="ruby-comment cmt"># RubyForge download page; we do not want one package</span>
1472
+ <span class="ruby-comment cmt"># per sub-section on the RubyForge download page!</span>
1473
+ <span class="ruby-comment cmt">#</span>
1474
+ <span class="ruby-identifier">uploader</span>[<span class="ruby-identifier">:add_release</span>, <span class="ruby-identifier">packages</span>.<span class="ruby-identifier">shift</span>]
1475
+
1476
+ <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">packages</span>.<span class="ruby-identifier">empty?</span>
1477
+ <span class="ruby-identifier">uploader</span>[<span class="ruby-identifier">:add_file</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">packages</span>]
1478
+ <span class="ruby-keyword kw">end</span>
1479
+
1480
+ <span class="ruby-identifier">puts</span> <span class="ruby-value str">&quot;Successfully published release packages to RubyForge.&quot;</span>
1481
+ <span class="ruby-keyword kw">end</span>
1482
+ <span class="ruby-keyword kw">end</span>
1483
+ <span class="ruby-keyword kw">end</span>
1484
+ <span class="ruby-keyword kw">end</span></pre>
1485
+ </div>
1486
+ </div>
1487
+
1488
+ </div>
1489
+
1490
+ </div>
1491
+ </div>
1492
+ </body>
1493
+ </html>