bee 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,108 +0,0 @@
1
- <!--
2
- Copyright 2006 Michel Casabianca <casa@sweetohm.net>
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- -->
16
-
17
- <h2>Scripts</h2>
18
-
19
- <p>Let's start with traditional <i>Hello World!</i> example:</p>
20
-
21
- <pre class="code"><code>- target: hello
22
- script:
23
- - rb: "name = ENV['USER'].capitalize"
24
- - "echo \"Hello #{name}!\""</code></pre>
25
-
26
- <p>A target script can be made of shell and/or Ruby scripts. Variables
27
- defined in Ruby scripts can be accessed in shell using Ruby syntax
28
- <code>#{variable}</code>. Each shell script is executed in its own
29
- context while Ruby variables all live in a global one that persist
30
- in the whole build. This script will output:</p>
31
-
32
- <pre class="code"><code>----------------------------------------------------------------------- hello --
33
- Hello Casa!
34
- OK</code></pre>
35
-
36
- <h2>Targets</h2>
37
-
38
- <p>You can set default target and dependencies as follows:</p>
39
-
40
- <pre class="code"><code>- build: hello
41
- default: hello
42
-
43
- - target: name
44
- script:
45
- - rb: "name = ENV['USER'].capitalize"
46
-
47
- - target: hello
48
- depends: name
49
- script:
50
- - "echo \"Hello #{name}!\""
51
- </code></pre>
52
-
53
- <p>When running without indicating any target, bee will run target
54
- <i>hello</i> (default one, as stated in <code>default</code> key).
55
- Nevertheless, this target depends on <i>name</i>, thus bee will first
56
- run target <i>name</i>, then <i>hello</i>. This will write on console:</p>
57
-
58
- <pre class="code"><code>------------------------------------------------------------------------ name --
59
- ----------------------------------------------------------------------- hello --
60
- Hello Casa!
61
- OK</code></pre>
62
-
63
- <h2>Properties</h2>
64
-
65
- <p>You can define build properies as follows:</p>
66
-
67
- <pre class="code"><code>- properties:
68
- - name: "casa"
69
- - capitalized: "#{name.capitalize}"
70
-
71
- - target: hello
72
- script:
73
- - "echo \"Hello #{capitalized}!\""</code></pre>
74
-
75
- <p>First, we set property <i>name</i> to <i>casa</i>, a simple string.
76
- Then, we set <i>capitalized</i> to <i>Casa</i>, using a Ruby expression.
77
- Properties can use values defined in other properties. Furthermore, we
78
- can use these properties in shell or Ruby scripts.</p>
79
-
80
- <h2>Context</h2>
81
-
82
- <p>Ruby scripts run in a global context that persist for the whole build.
83
- This context is similar to the place you write your code in IRB. In
84
- this context, you can define variables, functions or classes. You can
85
- define your own context in a file loaded at startup. This file is the
86
- place to define utility functions you would use in your embedded Ruby
87
- scripts.</p>
88
-
89
- <p>For instance, loading script <i>hello.rb</i>:</p>
90
-
91
- <pre class="code"><code>def say_hello(who)
92
- puts "Hello #{who}!"
93
- end</code></pre>
94
-
95
- <p>In following build file using <code>context</code> as follows:</p>
96
-
97
- <pre class="code"><code>- build: hello
98
- context: hello.rb
99
-
100
- - properties:
101
- - me: "Casa"
102
-
103
- - target: hello
104
- script:
105
- - rb: "say_hello(me)"</code></pre>
106
-
107
- <p>After this quick introduction, you should know enough to start writing
108
- your first build file. Enjoy!</p>
Binary file
@@ -1,49 +0,0 @@
1
- # Copyright 2006 Michel Casabianca <casa@sweetohm.net>
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- - menu: bee
16
-
17
- - title: Quick Start
18
- file: ../html/quickstart.html
19
- dest: index.html
20
- type: html
21
-
22
- - title: Downloads
23
- dest: http://rubyforge.org/frs/?group_id=2479
24
- type: link
25
-
26
- - title: Documentation
27
- file: ../html/documentation.html
28
- dest: documentation.html
29
- type: html
30
-
31
- - title: Source API
32
- dir: ../../build/api/
33
- dest: api
34
- type: dir
35
-
36
- - title: License
37
- file: ../../LICENSE
38
- dest: license.html
39
- type: text
40
-
41
- - title: Syntax check
42
- file: ../../build/syntax.txt
43
- dest: syntax.html
44
- type: text
45
-
46
- - title: Unit tests
47
- file: ../../build/tests.txt
48
- dest: tests.html
49
- type: text
@@ -1,42 +0,0 @@
1
- # Copyright 2006 Michel Casabianca <casa@sweetohm.net>
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- - description: >
16
- Here is the list of Bee release with new features and links to download.
17
- download: http://rubyforge.org/frs/?group_id=2479
18
-
19
- - release: alpha
20
- description: A simple night hack.
21
-
22
- - release: beta-1
23
- description: First public release.
24
- new:
25
- - Run Ruby scripts.
26
- - Load context on startup.
27
- - Added checks on build files syntax.
28
- - Documentation system.
29
-
30
- - release: 0.1.0
31
- description: First Gem package.
32
- new:
33
- - Distribution as a Gem package.
34
- - Template generation (-t option).
35
- fixed:
36
- - Directory in distribution archive postfixed with version.
37
-
38
- - release: 0.1.1
39
- description: Bug fix release.
40
- fixed:
41
- - Unit test suite.
42
- - Rdoc in ZIP archive.
@@ -1,17 +0,0 @@
1
- # Copyright 2006 Michel Casabianca <casa@sweetohm.net>
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- - Write documentation in RDoc format.
16
- - Freeze and document extension mechanism.
17
- - Write extension tasks to build bee on any platform.
@@ -1,464 +0,0 @@
1
- # Copyright 2006 Michel Casabianca <casa@sweetohm.net>
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- # Script to generate documentation.
16
-
17
- $:.unshift(File.join(File.dirname(__FILE__)))
18
- require 'bee'
19
- require 'erb'
20
- require 'fileutils'
21
- require 'yaml'
22
-
23
- module Bee
24
-
25
- # Module for Bee documentation generation.
26
- module Doc
27
-
28
- # Copyright notice.
29
- COPYRIGHT = 'BeeDoc version 0.1.1 (C) Michel Casabianca - 2006'
30
- # Console help.
31
- HELP = 'beedoc [-h] [-o dir] menu
32
- -h Print help about usage and exit.
33
- -o Directory where to generate documentation.
34
- menu Menu file to process.'
35
- # Exit value on error parsing command line
36
- EXIT_PARSING_CMDLINE = 1
37
- # Exit value on doc error
38
- EXIT_DOC_ERROR = 2
39
- # Exit value on unknown error
40
- EXIT_UNKNOWN_ERROR = 3
41
-
42
- #########################################################################
43
- # CLASS DOCERROR #
44
- #########################################################################
45
-
46
- class DocError < RuntimeError; end
47
-
48
- module DocErrorMixin
49
-
50
- # Convenient method to raise a DocError.
51
- # - message: error message.
52
- def error(message)
53
- raise DocError.new(message)
54
- end
55
-
56
- end
57
-
58
- #########################################################################
59
- # PARSE COMMAND LINE #
60
- #########################################################################
61
-
62
- # Parse command line and return arguments.
63
- def self.parse_command_line
64
- help = false
65
- output = nil
66
- require 'getoptlong'
67
- begin
68
- opts = GetoptLong.new(['--help', '-h', GetoptLong::NO_ARGUMENT ],
69
- ['--output', '-o', GetoptLong::REQUIRED_ARGUMENT])
70
- opts.each do |opt, arg|
71
- case opt
72
- when '--help'
73
- help = true
74
- when '--output'
75
- output = arg
76
- end
77
- end
78
- help = true if ARGV.length > 1
79
- menu = ARGV[0]
80
- return [help, output, menu]
81
- end
82
- end
83
-
84
- # Run BeeDoc from command line.
85
- def self.start_command_line
86
- begin
87
- help, output, menu = parse_command_line
88
- raise "No menu file" if not menu
89
- rescue
90
- puts "ERROR: parsing command line (type 'beedoc -h' for help): #{$!}"
91
- exit(EXIT_PARSING_CMDLINE)
92
- end
93
- begin
94
- if help
95
- puts COPYRIGHT
96
- puts HELP
97
- else
98
- Bee::Doc::Menu.new(menu).generate(output)
99
- puts "OK"
100
- end
101
- rescue DocError
102
- puts "ERROR: #{$!}"
103
- exit(EXIT_DOC_ERROR)
104
- rescue Exception => e
105
- puts "ERROR: #{$!}"
106
- puts e.backtrace.join("\n")
107
- exit(EXIT_UNKNOWN_ERROR)
108
- end
109
- end
110
-
111
- #########################################################################
112
- # CLASS MENU #
113
- #########################################################################
114
-
115
- class Menu
116
-
117
- include DocErrorMixin
118
-
119
- # Title for documentation.
120
- attr_reader :title
121
- # Generation date.
122
- attr_reader :date
123
- # List of menu entries.
124
- attr_reader :entries
125
- # Base directory.
126
- attr_reader :base
127
- # Contents for page being generated.
128
- attr_reader :contents
129
-
130
- # Constructor.
131
- # - file: menu file to load.
132
- def initialize(file)
133
- begin
134
- @base = File.dirname(file)
135
- source = File.read(file)
136
- menu = YAML::load(source)
137
- @entries = []
138
- error "Menu must be a list" unless menu.kind_of?(Array)
139
- error "Menu description must be first entry" unless
140
- menu[0].kind_of?(Hash) and menu[0]['menu']
141
- @title = menu[0]['menu']
142
- @date = Time.now
143
- for entry in menu[1..-1]
144
- @entries << Entry.new(entry, self)
145
- end
146
- rescue
147
- error "Error loading menu file: #{$!}"
148
- end
149
- end
150
-
151
- # Generate HTML documents.
152
- # - directory: where to generate documentation.
153
- def generate(directory)
154
- error "Destination directory '#{directory}' already exists" if
155
- File.exists?(directory)
156
- FileUtils.makedirs(directory)
157
- write_style_sheet = false
158
- for entry in @entries
159
- entry.generate(directory, @date)
160
- write_style_sheet = true if not entry.template
161
- end
162
- if write_style_sheet
163
- File.open(File.join(directory, 'stylesheet.css'), 'w') do |file|
164
- file.write(Entry::DEFAULT_STYLESHEET)
165
- end
166
- end
167
- end
168
-
169
- end
170
-
171
- #########################################################################
172
- # CLASS ENTRY #
173
- #########################################################################
174
-
175
- # A menu entry.
176
- class Entry
177
-
178
- include BuildErrorMixin
179
-
180
- # Parent menu.
181
- attr_reader :menu
182
- # Title.
183
- attr_reader :title
184
- # File.
185
- attr_reader :file
186
- # Destination file.
187
- attr_reader :dest
188
- # Directory.
189
- attr_reader :dir
190
- # File type.
191
- attr_reader :type
192
- # Table of contents.
193
- attr_reader :toc
194
- # Header depth for toc.
195
- attr_reader :header
196
- # Template for generation.
197
- attr_reader :template
198
- # Generation date.
199
- attr_reader :date
200
-
201
- # Constructor.
202
- # - entry: menu entry as a Hash.
203
- # - menu: the root menu for the entry.
204
- def initialize(entry, menu)
205
- # check keys in entry
206
- error "Unknown entry type '#{entry['type']}'" unless
207
- ['html', 'text', 'dir', 'link'].member?(entry['type'])
208
- error "A menu entry must be a Hash" unless entry.kind_of?(Hash)
209
- error "'title' key is mandatory in menu entries" unless entry['title']
210
- error "One of 'file' or 'dir' keys must be in a menu entry" unless
211
- (entry['file'] or entry['dir']) or entry['type'] == 'link'
212
- error "'file' and 'dir' keys can't be in a menu entry at the " +
213
- "same time" if entry['file'] and entry['dir']
214
- # save keys into fields
215
- @menu = menu
216
- @title = entry['title']
217
- @file = entry['file']
218
- @dest = entry['dest']
219
- @dir = entry['dir']
220
- @type = entry['type']
221
- @toc = entry['toc']
222
- @header = entry['header']
223
- @template = entry['template']
224
- end
225
-
226
- # Generate a menu entry.
227
- # - directory: destination directory.
228
- # - date: generation date.
229
- def generate(directory, date)
230
- return if type == 'link'
231
- @date = date
232
- # load template
233
- if @template
234
- template = ERB.new(File.read(@template))
235
- else
236
- template = ERB.new(DEFAULT_TEMPLATE)
237
- end
238
- if @dir
239
- # entry is a directory: copy it to destination directory
240
- puts "Copying directory '#{@dir}'..."
241
- FileUtils.cp_r(File.join(@menu.base, @dir),
242
- File.join(directory, dest))
243
- else
244
- # entry is a regular file: generate documentation with template
245
- puts "Generating '#{@dest}'..."
246
- @contents = File.read(File.join(@menu.base, @file))
247
- @contents = '<pre>' + escape_special_characters(@contents) +
248
- '</pre>' if text?
249
- result = template.result(get_binding)
250
- File.open(File.join(directory, @dest), 'w') do |file|
251
- file.write(result)
252
- end
253
- end
254
- end
255
-
256
- private
257
-
258
- # Tells if entry is a text one.
259
- def text?
260
- return type == 'text'
261
- end
262
-
263
- # Get a binding for ERB generation.
264
- def get_binding
265
- return binding
266
- end
267
-
268
- # Escape HTML special characters (such as & " ' < and >).
269
- # - string: string to process.
270
- # Return: processed string.
271
- def escape_special_characters(string)
272
- return string.gsub(/&/, '&amp;').gsub(/"/, '&quot;').
273
- gsub(/'/, '&apos;').gsub(/</, '&lt;').gsub(/>/, '&gt;')
274
- end
275
-
276
- # Default ERB template to generate HTML.
277
- DEFAULT_TEMPLATE = '<html>
278
- <head>
279
- <title><%= @menu.title %></title>
280
- <link rel="stylesheet" type="text/css" href="stylesheet.css">
281
- </head>
282
- <body marginwidth="0" marginheight="0">
283
- <table class="frame" width="100%" height="100%">
284
- <tr>
285
- <td class="frame" colspan="2"
286
- align="right" valign="middle"
287
- height="70">
288
- <h1 class="title"><b><%= @menu.title %>&#xA0;&#xA0;</b></h1>
289
- </td>
290
- </tr>
291
- <tr>
292
- <td class="ruller" colspan="2"
293
- align="left" valign="middle"
294
- height="10">
295
- <font size="-1">Generated on <%= @date.strftime("%Y-%m-%d %H:%M:%S") %></font>
296
- </td>
297
- </tr>
298
- <tr>
299
- <td class="menu"
300
- align="left" valign="top"
301
- width="150">
302
- <%
303
- for entry in @menu.entries
304
- link = entry.dest
305
- link += \'/index.html\' if entry.dir
306
- %>
307
- <a class="menu" href="<%= link %>"><%= entry.title %></a><br>
308
- <%
309
- end
310
- %>
311
- </td>
312
- <td class="text"
313
- align="left" valign="top">
314
- <center><h1 class="title"><b><%= @title %></b></h1></center>
315
- <%= @contents %>
316
- </td>
317
- </tr>
318
- </table>
319
- </body>
320
- </html>'
321
-
322
- public
323
-
324
- # Default style sheet.
325
- DEFAULT_STYLESHEET = '
326
- h1,h2,h3 {
327
- font-family: Verdana, Helvetica, Arial, sans-serif;
328
- color: #FF9000;
329
- }
330
-
331
- h1.title {
332
- font-family: Verdana, Helvetica, Arial, sans-serif;
333
- font-size: 30pt;
334
- color: #000000
335
- }
336
-
337
- table.frame {
338
- border-width: 0px;
339
- border-spacing: 0px;
340
- }
341
-
342
- td.frame {
343
- padding: 0px;
344
- text-align: right;
345
- border: thin solid #OOO000;
346
- }
347
-
348
- td.text {
349
- padding: 10px;
350
- font-family: Verdana, Helvetica, Arial, sans-serif;
351
- font-size: 10pt;
352
- }
353
-
354
- td.ruller {
355
- padding: 3px;
356
- background-color: #000000;
357
- color: #FFFFFF;
358
- font-family: Verdana, Helvetica, Arial, sans-serif;
359
- font-size: 10pt;
360
- }
361
-
362
- td.menu {
363
- padding: 10px;
364
- background-color: #FF9000;
365
- font-family: Verdana, Helvetica, Arial, sans-serif;
366
- font-size: 12pt;
367
- }
368
-
369
- table.toc {
370
- text-align: left;
371
- border-width: 0pt;
372
- background-color: #F9F9F9;
373
- font-family: Verdana, Helvetica, Arial, sans-serif;
374
- font-size: 10pt;
375
- }
376
-
377
- p {
378
- font-family: Verdana, Helvetica, Arial, sans-serif;
379
- font-size: 10pt;
380
- }
381
-
382
- table {
383
- font-family: Verdana, Helvetica, Arial, sans-serif;
384
- font-size: 10pt;
385
- border: medium solid #000000;
386
- border-collapse: collapse;
387
- }
388
-
389
- th {
390
- padding: 5px;
391
- background-color: #FF9000;
392
- border: thin solid #OOO000;
393
- text-align: left;
394
- }
395
-
396
- td {
397
- padding: 5px;
398
- border: thin solid #OOO000;
399
- text-align: left;
400
- }
401
-
402
- li {
403
- font-family: Verdana, Helvetica, Arial, sans-serif;
404
- font-size: 10pt;
405
- list-style: square;
406
- }
407
-
408
- a:link {
409
- text-decoration: none;
410
- color: #FF9000;
411
- }
412
-
413
- a:visited {
414
- text-decoration: none;
415
- color: #000000;
416
- }
417
-
418
- a:active {
419
- text-decoration: none;
420
- color: #FFFFFF;
421
- background-color: #000000;
422
- }
423
-
424
- a:hover {
425
- text-decoration: none;
426
- color: #FFFFFF;
427
- background-color: #000000;
428
- }
429
-
430
- a.menu:link {
431
- text-decoration: none;
432
- color: #000000;
433
- }
434
-
435
- a.menu:visited {
436
- text-decoration: none;
437
- color: #000000;
438
- }
439
-
440
- a.menu:active {
441
- text-decoration: none;
442
- color: #000000;
443
- }
444
-
445
- a.menu:hover {
446
- text-decoration: none;
447
- color: #FFFFFF;
448
- background-color: #000000;
449
- }
450
-
451
- pre.code {
452
- clear: both;
453
- overflow: auto;
454
- background-color: #EFEFEF;
455
- padding: 0;
456
- padding: 1.0em;
457
- }
458
- '
459
-
460
- end
461
-
462
- end
463
-
464
- end