bee 0.10.2 → 0.11.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,4 +1,4 @@
1
- # Copyright 2006-2010 Michel Casabianca <michel.casabianca@gmail.com>
1
+ # Copyright 2006-2011 Michel Casabianca <michel.casabianca@gmail.com>
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,7 +12,9 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # Module for Bee core classes.
15
+ require 'rubygems'
16
+ require 'bee_util'
17
+
16
18
  module Bee
17
19
 
18
20
  # Class for a target. It is built from the YAML build file and manages a
@@ -50,12 +52,9 @@ module Bee
50
52
  @targets = targets
51
53
  @name = object[Target::KEY]
52
54
  error "Target name cannot be 'null'" if @name == nil
53
- @depends = object['depends']||[]
54
- @depends = Array(@depends)
55
+ @depends = Array(object['depends']||[])
55
56
  @description = object['description']
56
- @script = object['script']
57
- @script = [@script] if @script.kind_of?(String)
58
- @script = [] if not @script
57
+ @script = Array(object['script']||[])
59
58
  end
60
59
 
61
60
  # Run target.
@@ -102,10 +101,12 @@ module Bee
102
101
  # call super target
103
102
  targets.call_super(self, dry)
104
103
  else
105
- # must be a task
104
+ # bee task
106
105
  run_bee_task(task, dry)
107
106
  end
108
107
  end
108
+ else
109
+ raise "Task must be a string or a hash"
109
110
  end
110
111
  end
111
112
 
@@ -129,6 +130,8 @@ module Bee
129
130
  return if dry
130
131
  begin
131
132
  @targets.build.context.evaluate_script(script)
133
+ rescue Interrupt
134
+ raise $!
132
135
  rescue Exception
133
136
  error "Error running Ruby script: #{$!}"
134
137
  end
@@ -144,6 +147,7 @@ module Bee
144
147
 
145
148
  # Run a given construct.
146
149
  # - construct: construct to run as a Hash.
150
+ # -dry: tells if we are running in dry mode. Defaults to false.
147
151
  def run_construct(construct, dry=false)
148
152
  @listener.task(construct) if @listener
149
153
  return if dry
@@ -174,8 +178,10 @@ module Bee
174
178
  unknown_keys = task.keys - ['if', 'then', 'else']
175
179
  error "If-then-else construct may only include 'if', 'then' and 'else' entries" if
176
180
  unknown_keys.length > 0
177
- error "If entry in if-then-else construct must be a string" if
178
- not task['if'].kind_of?(String)
181
+ error "If entry in if-then-else construct must be a string, a symbol or a boolean" if
182
+ not task['if'].kind_of?(String) and
183
+ not task['if'].kind_of?(Symbol) and
184
+ not (task['if'].kind_of?(TrueClass) or task['if'].kind_of?(FalseClass))
179
185
  error "Then entry in if-then-else construct must be a list" if
180
186
  not task['then'].kind_of?(Array)
181
187
  error "Else entry in if-then-else construct must be a list" if
@@ -214,20 +220,24 @@ module Bee
214
220
  def construct_for(task, dry)
215
221
  # test entries
216
222
  error "For-in-do construct must include 'in' and 'do' entries" if
217
- not task.keys.include?('in') or not task.keys.include?('do')
223
+ not task.keys.include?('in') or
224
+ not task.keys.include?('do')
218
225
  unknown_keys = task.keys - ['for', 'in', 'do']
219
226
  error "For-in-do construct may only include 'for', 'in' and 'do' entries" if
220
227
  unknown_keys.length > 0
221
228
  error "For entry in for-in-do construct must be a string" if
222
229
  not task['for'].kind_of?(String)
223
- error "In entry in for-in-do construct must be a list or a string" if
224
- not task['in'].kind_of?(Enumerable) and not task['in'].kind_of?(String)
230
+ error "In entry in for-in-do construct must be a list, a string or a symbol" if
231
+ not task['in'].kind_of?(Enumerable) and
232
+ not task['in'].kind_of?(String) and
233
+ not task['in'].kind_of?(Symbol)
225
234
  error "Do entry in for-in-do construct must be a list" if
226
235
  not task['do'].kind_of?(Array)
227
236
  # iterate over list
228
- if task['in'].kind_of?(String)
229
- enumerable = evaluate(@targets.build.context.
230
- evaluate_object(task['in']))
237
+ if task['in'].kind_of?(String) or task['in'].kind_of?(Symbol)
238
+ enumerable = evaluate(task['in'])
239
+ error "In entry in for-in-do construct must result in an enumerable" if
240
+ not enumerable.kind_of?(Enumerable)
231
241
  else
232
242
  enumerable = task['in']
233
243
  end
@@ -254,13 +264,14 @@ module Bee
254
264
  error "Try entry in try-catch construct must be a list" if
255
265
  not task['try'].kind_of?(Array)
256
266
  error "Catch entry in try-catch construct must be a list" if
257
- not task['catch'].kind_of?(Array)
267
+ task['catch'] and not task['catch'].kind_of?(Array)
258
268
  # try and catch errors
259
269
  begin
260
270
  run_block(task['try'], dry)
261
271
  rescue
262
272
  @targets.build.listener.recover if @targets.build.listener
263
- run_block(task['catch'], dry)
273
+ run_block(task['catch'], dry) if task['catch']
274
+
264
275
  end
265
276
  end
266
277
 
@@ -276,7 +287,13 @@ module Bee
276
287
  # Evaluate a given expression and raise a BuildError if an error happens.
277
288
  def evaluate(expression)
278
289
  begin
279
- return @targets.build.context.evaluate_script(expression)
290
+ if expression.kind_of?(String)
291
+ return @targets.build.context.evaluate_script(expression)
292
+ elsif (expression.kind_of?(TrueClass) or expression.kind_of?(FalseClass))
293
+ return expression
294
+ else
295
+ return @targets.build.context.evaluate_object(expression)
296
+ end
280
297
  rescue
281
298
  error "Error evaluating expression: #{$!}"
282
299
  end
@@ -0,0 +1,147 @@
1
+ # Copyright 2006-2011 Michel Casabianca <michel.casabianca@gmail.com>
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
+ require 'rubygems'
16
+ require 'bee_util'
17
+ require 'bee_target'
18
+
19
+ module Bee
20
+
21
+ # Class to manage targets in a build.
22
+ class Targets
23
+
24
+ include Bee::Util::BuildErrorMixin
25
+
26
+ # The build.
27
+ attr_reader :build
28
+ # Targets hash by name.
29
+ attr_reader :hash
30
+ # List of targets that already ran.
31
+ attr_reader :already_run
32
+ # Default target.
33
+ attr_accessor :default
34
+
35
+ # Constructor.
36
+ # - build: build object.
37
+ def initialize(build)
38
+ @build = build
39
+ @hash = {}
40
+ @already_run = []
41
+ end
42
+
43
+ # Add a new target.
44
+ # - object: object tree resulting from YAML build file parsing.
45
+ def add(object)
46
+ begin
47
+ target = Target.new(object, self)
48
+ rescue
49
+ error "Error parsing target '#{object[Bee::Target::KEY]}': #{$!}"
50
+ end
51
+ error "Duplicate target definition: '#{target.name}'" if
52
+ @hash.has_key?(target.name)
53
+ @hash[target.name] = [target]
54
+ @default = target.name if !@default
55
+ end
56
+
57
+ # Extend parent targets.
58
+ # - parent: parent targets.
59
+ def extend(parent)
60
+ # set appropriate targets for targets of parent
61
+ for targets in parent.hash.values
62
+ for target in targets
63
+ target.targets = self
64
+ end
65
+ end
66
+ # insert parent targets before current ones
67
+ for name in parent.hash.keys
68
+ if @hash[name]
69
+ @hash[name] = parent.hash[name] + @hash[name]
70
+ # clean dependencies for redefined targets
71
+ for target in parent.hash[name]
72
+ target.depends.clear
73
+ end
74
+ # copy documentation of parent if target not documented
75
+ if not @hash[name].last.description
76
+ description = nil
77
+ for target in parent.hash[name]
78
+ description = target.description || description
79
+ end
80
+ @hash[name].last.description = description
81
+ end
82
+ else
83
+ @hash[name] = parent.hash[name]
84
+ end
85
+ end
86
+ # set default default target to parent one if none was set
87
+ @default = @default || parent.default
88
+ end
89
+
90
+ # Run a given target.
91
+ # - target: the target to run.
92
+ # - dry: tells if we run in dry mode. Defaults to false.
93
+ def run_target(target, dry=false)
94
+ error "Target '#{target}' not found" if not @hash[target]
95
+ if not @already_run.include?(target)
96
+ @already_run << target
97
+ @hash[target].last.run(dry)
98
+ end
99
+ end
100
+
101
+ # Run targets.
102
+ # - targets: list of target names to run.
103
+ def run(targets, dry)
104
+ error "No default target given" if (!@default and targets.length == 0)
105
+ targets = [@default] if targets.length == 0
106
+ for target in targets
107
+ run_target(target, dry)
108
+ @already_run.clear
109
+ end
110
+ end
111
+
112
+ # Call super target.
113
+ # - target: target to call super onto.
114
+ def call_super(target, dry=false)
115
+ index = @hash[target.name].index(target)
116
+ error "No super target to call for '#{target.name}'" if index == 0
117
+ index -= 1
118
+ @hash[target.name][index].run(dry)
119
+ end
120
+
121
+ # Tells if a given target is last in hierarchy.
122
+ # - target: given target.
123
+ def is_last(target)
124
+ index = @hash[target.name].index(target)
125
+ last = @hash[target.name].size - 1
126
+ return index == last
127
+ end
128
+
129
+ # Return targets description as a hash of descriptions indexed by
130
+ # target name. Dependencies are added after target description.
131
+ def description
132
+ description = {}
133
+ for name in @hash.keys
134
+ text = @hash[name].last.description
135
+ if @hash[name].last.depends and @hash[name].last.depends.length > 0
136
+ depends = ' [' + @hash[name].last.depends.join(', ') + ']'
137
+ else
138
+ depends = nil
139
+ end
140
+ description[name] = (text ? text : '') + (depends ? depends : '')
141
+ end
142
+ return description
143
+ end
144
+
145
+ end
146
+
147
+ end
@@ -1,4 +1,4 @@
1
- # Copyright 2006-2010 Michel Casabianca <michel.casabianca@gmail.com>
1
+ # Copyright 2006-2011 Michel Casabianca <michel.casabianca@gmail.com>
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -13,8 +13,8 @@
13
13
  # limitations under the License.
14
14
 
15
15
  require 'rubygems'
16
- require 'bee'
17
- require 'bee_task'
16
+ require 'bee_build'
17
+ require 'bee_task_package'
18
18
  require 'bee_util'
19
19
  require 'erb'
20
20
  require 'fileutils'
@@ -28,7 +28,7 @@ module Bee
28
28
 
29
29
  # Package for default tasks (tasks with no package).
30
30
  class Default < Package
31
-
31
+
32
32
  ######################################################################
33
33
  # MISCELLANEOUS TASKS #
34
34
  ######################################################################
@@ -141,7 +141,7 @@ module Bee
141
141
  @build.context.set_property(property, value)
142
142
  end
143
143
 
144
- # Trow a build error with a given message.
144
+ # Throw a build error with a given message.
145
145
  #
146
146
  # - message: the error message. Will be printed on the console as the
147
147
  # build failure reason.
@@ -156,6 +156,9 @@ module Bee
156
156
  error message
157
157
  end
158
158
 
159
+ # Alias for throw.
160
+ alias :raise :throw
161
+
159
162
  # Get a given URL and store its content in a given file. Parameters
160
163
  # is a Hash with following entries:
161
164
  #
@@ -171,7 +174,7 @@ module Bee
171
174
  #
172
175
  # - get:
173
176
  # url: http://rubyforge.org/frs/download.php/22185/bee-0.4.0.zip
174
- def get(parameters)
177
+ def http_get(parameters)
175
178
  params_desc = {
176
179
  :url => { :mandatory => true, :type => :string },
177
180
  :dest => { :mandatory => false, :type => :string },
@@ -211,7 +214,6 @@ module Bee
211
214
  @build.context.set_property(prop, content)
212
215
  end
213
216
  end
214
-
215
217
 
216
218
  # Send an email using SMTP.
217
219
  #
@@ -342,7 +344,7 @@ EOF
342
344
  puts "Linking #{files.length} file(s) to '#{new}'"
343
345
  begin
344
346
  FileUtils.ln_s(files, new)
345
- rescue
347
+ rescue Exception
346
348
  error "Error making the link: #{$!}"
347
349
  end
348
350
  end
@@ -389,7 +391,7 @@ EOF
389
391
  else
390
392
  FileUtils.chmod(mode, files)
391
393
  end
392
- rescue
394
+ rescue Exception
393
395
  error "Error changing permissions: #{$!}"
394
396
  end
395
397
  end
@@ -439,10 +441,10 @@ EOF
439
441
  else
440
442
  FileUtils.chown(user, group, files)
441
443
  end
442
- rescue
444
+ rescue Exception
443
445
  error "Error changing owner: #{$!}"
444
446
  end
445
- end
447
+ end
446
448
  end
447
449
 
448
450
  # Make a directory, and parent directories if necessary. Doesn't
@@ -462,7 +464,7 @@ EOF
462
464
  puts "Creating directory '#{dir}'"
463
465
  begin
464
466
  FileUtils.makedirs(dir)
465
- rescue
467
+ rescue Exception
466
468
  error "Error creating directory '#{dir}': #{$!}"
467
469
  end
468
470
  end
@@ -498,7 +500,7 @@ EOF
498
500
  puts "Copying #{nb_copies} file(s) to '#{dest}'"
499
501
  begin
500
502
  FileUtils.cp_r(src, dest)
501
- rescue
503
+ rescue Exception
502
504
  error "Error copying file(s): #{$!}"
503
505
  end
504
506
  end
@@ -533,7 +535,7 @@ EOF
533
535
  puts "Moving #{nb_moves} file(s) to '#{dest}'"
534
536
  begin
535
537
  FileUtils.mv(src, dest)
536
- rescue
538
+ rescue Exception
537
539
  error "Error moving file(s): #{$!}"
538
540
  end
539
541
  end
@@ -725,7 +727,7 @@ EOF
725
727
  for file in files
726
728
  begin
727
729
  FileUtils.rm(file)
728
- rescue
730
+ rescue Exception
729
731
  error "Error deleting files: #{$!}"
730
732
  end
731
733
  end
@@ -751,7 +753,7 @@ EOF
751
753
  for dir in dirs
752
754
  begin
753
755
  FileUtils.rm_rf(dir)
754
- rescue
756
+ rescue Exception
755
757
  error "Error deleting directory(ies): #{$!}"
756
758
  end
757
759
  end
@@ -788,7 +790,7 @@ EOF
788
790
  puts "Touching #{size} file(s)" if size > 0
789
791
  begin
790
792
  FileUtils.touch(files)
791
- rescue
793
+ rescue Exception
792
794
  error "Error touching file(s): #{$!}"
793
795
  end
794
796
  end
@@ -844,27 +846,27 @@ EOF
844
846
 
845
847
  # Load a YAML file in a given property.
846
848
  #
847
- # - prop: the property name to set with YAML parsed content.
848
849
  # - file: the YAML file name to load.
850
+ # - prop: the property name to set with YAML parsed content.
849
851
  #
850
852
  # Example
851
853
  #
852
854
  # - yaml_load:
853
- # prop: "my_list"
854
855
  # file: "my_list.yml"
856
+ # prop: "my_list"
855
857
  def yaml_load(params)
856
858
  params_desc = {
859
+ :file => { :mandatory => true, :type => :string },
857
860
  :prop => { :mandatory => true, :type => :string },
858
- :file => { :mandatory => true, :type => :string }
859
861
  }
860
862
  check_parameters(params, params_desc)
861
- prop = params[:prop]
862
863
  file = params[:file]
864
+ prop = params[:prop]
863
865
  error "YAML file '#{file}' not found" if not File.exists?(file)
864
866
  script = "#{prop} = YAML.load(File.read('#{file}'))"
865
867
  begin
866
868
  @build.context.evaluate_script(script)
867
- rescue
869
+ rescue Exception
868
870
  error "Error loading YAML file '#{file}': #{$!}"
869
871
  end
870
872
  end
@@ -890,7 +892,7 @@ EOF
890
892
  script = "File.open('#{file}', 'w') {|f| f.write(YAML.dump(#{prop}))}"
891
893
  begin
892
894
  @build.context.evaluate_script(script)
893
- rescue
895
+ rescue Exception
894
896
  error "Error dumping YAML file '#{file}': #{$!}"
895
897
  end
896
898
  end
@@ -958,7 +960,8 @@ EOF
958
960
  def test(params)
959
961
  require 'test/unit'
960
962
  params_desc = {
961
- :root => { :mandatory => false, :type => :string },
963
+ :root => { :mandatory => false, :type => :string,
964
+ :default => '.' },
962
965
  :includes => { :mandatory => true, :type => :string },
963
966
  :excludes => { :mandatory => false, :type => :string },
964
967
  :dotmatch => { :mandatory => false, :type => :boolean,
@@ -975,8 +978,9 @@ EOF
975
978
  error "Test directory '#{dir}' not found" if
976
979
  not (File.exists?(dir) and File.directory?(dir))
977
980
  files = filter_files(includes, excludes, root, dotmatch)
981
+ files.map! { |file| File.expand_path(File.join(root, file)) }
978
982
  for file in files
979
- load File.join(root || '.', file)
983
+ load file
980
984
  end
981
985
  size = (files.kind_of?(Array) ? files.size : 1)
982
986
  puts "Running #{size} unit test(s)"
@@ -1051,15 +1055,15 @@ EOF
1051
1055
  end
1052
1056
  begin
1053
1057
  result = template.result(@build.context.context_binding)
1054
- rescue
1058
+ rescue Exception
1055
1059
  error "Error processing ERB: #{$!}"
1056
1060
  end
1057
1061
  # write result in file or set property
1058
1062
  if dest
1059
1063
  begin
1060
1064
  File.open(dest, 'w') { |file| file.write(result) }
1061
- rescue
1062
- error "Error writing ERB processing result in file: #{$!}"
1065
+ rescue Exception
1066
+ error "Error writing ERB result in file: #{$!}"
1063
1067
  end
1064
1068
  else
1065
1069
  @build.context.set_property(property, result)
@@ -1111,7 +1115,7 @@ EOF
1111
1115
  begin
1112
1116
  rdoc = RDoc::RDoc.new
1113
1117
  rdoc.document(command_line)
1114
- rescue
1118
+ rescue Exception
1115
1119
  error "Error generating RDoc: #{$!}"
1116
1120
  end
1117
1121
  end
@@ -1172,7 +1176,7 @@ EOF
1172
1176
  begin
1173
1177
  build = Bee::Build.load(file, false, props)
1174
1178
  build.run(target, @build.listener.clone)
1175
- rescue
1179
+ rescue Exception
1176
1180
  error "Error invoking build file '#{file}': #{$!}"
1177
1181
  end
1178
1182
  end
@@ -1227,16 +1231,16 @@ EOF
1227
1231
  # build the archive
1228
1232
  puts "Building ZIP archive '#{dest}'"
1229
1233
  begin
1230
- zipfile = Zip::ZipFile.open(dest, Zip::ZipFile::CREATE) do |zip|
1234
+ Zip::ZipFile.open(dest, Zip::ZipFile::CREATE) do |zip|
1231
1235
  for file in files
1232
1236
  path = (root == nil ? file : File.join(root, file))
1233
1237
  entry = prefix ? File.join(prefix, file) : file
1234
- puts "Adding '#{entry}'" if @build.listener.verbose
1238
+ puts "Adding '#{entry}'" if @verbose
1235
1239
  zip.add(entry, path)
1236
1240
  end
1237
1241
  zip.close
1238
1242
  end
1239
- rescue
1243
+ rescue Exception
1240
1244
  error "Error building ZIP archive: #{$!}"
1241
1245
  end
1242
1246
  end
@@ -1269,7 +1273,7 @@ EOF
1269
1273
  puts "Extracting ZIP file '#{src}' to '#{dest}'"
1270
1274
  begin
1271
1275
  Zip::ZipFile.foreach(src) do |entry|
1272
- puts "Writing '#{entry}'" if @build.listener.verbose
1276
+ puts "Writing '#{entry}'" if @verbose
1273
1277
  tofile = File.join(dest, entry.name)
1274
1278
  if entry.file?
1275
1279
  dir = File.dirname(tofile)
@@ -1279,7 +1283,7 @@ EOF
1279
1283
  FileUtils.makedirs(tofile)
1280
1284
  end
1281
1285
  end
1282
- rescue
1286
+ rescue Exception
1283
1287
  error "Error extracting ZIP archive: #{$!}"
1284
1288
  end
1285
1289
  end
@@ -1331,7 +1335,7 @@ EOF
1331
1335
  Dir.chdir(root) if root
1332
1336
  Archive::Tar::Minitar::Output.open(abs_dest) do |tarfile|
1333
1337
  for file in files
1334
- puts "Adding '#{file}'" if @build.listener.verbose
1338
+ puts "Adding '#{file}'" if @verbose
1335
1339
  Archive::Tar::Minitar.pack_file(file, tarfile)
1336
1340
  end
1337
1341
  end
@@ -1373,7 +1377,7 @@ EOF
1373
1377
  output.write(input.read)
1374
1378
  output.close
1375
1379
  end
1376
- rescue
1380
+ rescue Exception
1377
1381
  error "Error generating GZIP archive: #{$!}"
1378
1382
  end
1379
1383
  end
@@ -1422,7 +1426,7 @@ EOF
1422
1426
  output.write(input.read)
1423
1427
  output.close
1424
1428
  end
1425
- rescue
1429
+ rescue Exception
1426
1430
  error "Error expanding GZIP archive: #{$!}"
1427
1431
  end
1428
1432
  end
@@ -1478,11 +1482,11 @@ EOF
1478
1482
  Archive::Tar::Minitar::Output.
1479
1483
  open(Zlib::GzipWriter.new(File.open(abs_dest, 'wb'))) do |tgz|
1480
1484
  for file in files
1481
- puts "Adding '#{file}'" if @build.listener.verbose
1485
+ puts "Adding '#{file}'" if @verbose
1482
1486
  Archive::Tar::Minitar.pack_file(file, tgz)
1483
1487
  end
1484
1488
  end
1485
- rescue
1489
+ rescue Exception
1486
1490
  error "Error generating TARGZ archive: #{$!}"
1487
1491
  ensure
1488
1492
  Dir.chdir(current_dir)
@@ -1524,7 +1528,7 @@ EOF
1524
1528
  else
1525
1529
  Archive::Tar::Minitar.unpack(src, dest)
1526
1530
  end
1527
- rescue
1531
+ rescue Exception
1528
1532
  error "Error extracting TAR archive: #{$!}"
1529
1533
  end
1530
1534
  end
@@ -1563,7 +1567,7 @@ EOF
1563
1567
  ftp.close
1564
1568
  end
1565
1569
  puts "Connection to FTP host '#{host}' sucessful"
1566
- rescue
1570
+ rescue Exception
1567
1571
  error "Error connecting to FTP host: #{$!}"
1568
1572
  end
1569
1573
  end
@@ -1615,7 +1619,7 @@ EOF
1615
1619
  end
1616
1620
  ftp.close
1617
1621
  end
1618
- rescue
1622
+ rescue Exception
1619
1623
  error "Error getting file '#{basename}': #{$!}"
1620
1624
  end
1621
1625
  end
@@ -1667,7 +1671,7 @@ EOF
1667
1671
  end
1668
1672
  ftp.close
1669
1673
  end
1670
- rescue
1674
+ rescue Exception
1671
1675
  error "Error putting file '#{basename}': #{$!}"
1672
1676
  end
1673
1677
  end
@@ -1707,7 +1711,7 @@ EOF
1707
1711
  ftp.mkdir(dir)
1708
1712
  ftp.close
1709
1713
  end
1710
- rescue
1714
+ rescue Exception
1711
1715
  error "Error making directory '#{basename}': #{$!}"
1712
1716
  end
1713
1717
  end
@@ -1719,18 +1723,19 @@ EOF
1719
1723
  # If construct will evaluate the expression in the 'if' entry and run
1720
1724
  # block in the 'then' entry or 'else' entry accordingly.
1721
1725
  #
1722
- # - if: the condition to evaluate. This is a Ruby expression evaluated
1723
- # in the build context.
1724
- # - then: block that is evaluated if confition in if is true.
1725
- # - else: block that is evaluated if confition in if is false.
1726
+ # - if: the condition to evaluate. This is a Ruby expression (thus a
1727
+ # string) evaluated in the build context, a symbol that refers to a
1728
+ # property or a boolean.
1729
+ # - then: block that is evaluated if condition in if is true.
1730
+ # - else: block that is evaluated if condition in if is false.
1726
1731
  #
1727
1732
  # Example
1728
1733
  #
1729
1734
  # - if: RUBY_PLATFORM =~ /darwin/
1730
1735
  # then:
1731
- # - print: Hello, I'm a Mac
1736
+ # - print: Hello, I'm a Mac
1732
1737
  # else:
1733
- # - print: Hello, I'm a PC
1738
+ # - print: Hello, I'm a PC
1734
1739
  def if
1735
1740
  end
1736
1741
 
@@ -1745,8 +1750,8 @@ EOF
1745
1750
  #
1746
1751
  # - while: i > 0
1747
1752
  # do:
1748
- # - print: :i
1749
- # - rb: i -= 1
1753
+ # - print: :i
1754
+ # - rb: i -= 1
1750
1755
  def while
1751
1756
  end
1752
1757
 
@@ -1754,10 +1759,11 @@ EOF
1754
1759
  # a property which name is in the 'for' entry and running the block in
1755
1760
  # the 'do' entry for each value.
1756
1761
  #
1757
- # - for: the name of the property which receives values of the iteration.
1758
- # - in: a list on which to iterate. This can be a list or a ruby
1759
- # expression to evaluate in the context of the build to obtain the
1760
- # Enumerable on which to iterate.
1762
+ # - for: the name of the property which receives values of the iteration,
1763
+ # as a string.
1764
+ # - in: a list on which to iterate. This can be a list, a ruby expression
1765
+ # to evaluate in the context of the build to obtain the Enumerable on
1766
+ # which to iterate or a symbol that refers to a property that is a list.
1761
1767
  # - do: the block to run at each iteration.
1762
1768
  #
1763
1769
  # Example
@@ -1768,6 +1774,18 @@ EOF
1768
1774
  # - print: "Creating #{file}..."
1769
1775
  # - touch: :file
1770
1776
  #
1777
+ # The same using a reference to a property that is a list:
1778
+ #
1779
+ # - properties:
1780
+ # list: ['foo', 'bar']
1781
+ #
1782
+ # - target: test
1783
+ # script:
1784
+ # - for: name
1785
+ # in: :list
1786
+ # do:
1787
+ # - print: "Hi #{name}!"
1788
+ #
1771
1789
  # To iterate five times, we could write (using a Ruby Range):
1772
1790
  #
1773
1791
  # - for: i
@@ -1793,10 +1811,10 @@ EOF
1793
1811
  # Example:
1794
1812
  #
1795
1813
  # - try:
1796
- # - print: "In the try block"
1797
- # - throw: "Something went terribly wrong!"
1814
+ # - print: "In the try block"
1815
+ # - throw: "Something went terribly wrong!"
1798
1816
  # catch:
1799
- # - print: "An error occured"
1817
+ # - print: "An error occured"
1800
1818
  def try
1801
1819
  end
1802
1820