bee 0.4.0 → 0.5.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.
- data/README +1 -1
- data/bin/bee +1 -1
- data/bin/bee.bat +1 -1
- data/egg/package.yml +100 -0
- data/egg/package/bee_task.erb +25 -0
- data/egg/package/build.erb +70 -0
- data/egg/package/egg.yml +58 -0
- data/egg/package/egg_build.erb +57 -0
- data/egg/package/egg_launcher.erb +6 -0
- data/egg/package/egg_script.rb +31 -0
- data/egg/package/gem_spec.erb +23 -0
- data/egg/package/license +202 -0
- data/egg/package/readme.erb +23 -0
- data/egg/package/test.erb +28 -0
- data/egg/package/test_build.erb +16 -0
- data/{test → egg/package}/test_build.rb +1 -1
- data/{test → egg/package}/test_build_listener.rb +3 -1
- data/{test/ts_bee.rb → egg/package/test_suite.rb} +1 -1
- data/lib/bee.rb +468 -167
- data/lib/bee_console.rb +174 -94
- data/lib/bee_task.rb +121 -19
- data/lib/bee_task_default.rb +1016 -229
- data/lib/bee_util.rb +217 -64
- metadata +73 -58
- data/test/tc_bee_build.rb +0 -216
- data/test/tc_bee_console.rb +0 -106
- data/test/tc_bee_console_formatter.rb +0 -81
- data/test/tc_bee_context.rb +0 -84
- data/test/tc_bee_task_default.rb +0 -467
- data/test/tc_bee_util.rb +0 -85
- data/test/tmp_test_case.rb +0 -58
data/lib/bee_task_default.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2006-
|
1
|
+
# Copyright 2006-2008 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.
|
@@ -15,6 +15,8 @@
|
|
15
15
|
require 'bee'
|
16
16
|
require 'bee_task'
|
17
17
|
require 'bee_util'
|
18
|
+
require 'erb'
|
19
|
+
require 'fileutils'
|
18
20
|
|
19
21
|
module Bee
|
20
22
|
|
@@ -23,18 +25,19 @@ module Bee
|
|
23
25
|
# Package for default tasks (tasks with no package).
|
24
26
|
class Default < Package
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
#
|
28
|
+
######################################################################
|
29
|
+
# MISCELLANEOUS TASKS #
|
30
|
+
######################################################################
|
31
|
+
|
32
|
+
# Print a message on console. If message is not a string, this task
|
33
|
+
# outputs the inspected value of the object.
|
31
34
|
#
|
32
35
|
# - message: message to print.
|
33
36
|
#
|
34
37
|
# Example
|
35
38
|
#
|
36
|
-
# -
|
37
|
-
def
|
39
|
+
# - echo: "Hello World!"
|
40
|
+
def echo(message)
|
38
41
|
case message
|
39
42
|
when String
|
40
43
|
puts message
|
@@ -42,7 +45,138 @@ module Bee
|
|
42
45
|
puts message.inspect
|
43
46
|
end
|
44
47
|
end
|
45
|
-
|
48
|
+
|
49
|
+
# Alias for echo.
|
50
|
+
alias :print :echo
|
51
|
+
|
52
|
+
# Wait for a given amount of time.
|
53
|
+
#
|
54
|
+
# - time: time to wait, in seconds, as an integer or float.
|
55
|
+
#
|
56
|
+
# Example
|
57
|
+
#
|
58
|
+
# - sleep: 3.5
|
59
|
+
def sleep(time)
|
60
|
+
error "sleep parameter must be a float or a integer" if
|
61
|
+
not time.kind_of?(Numeric)
|
62
|
+
seconds = time.to_f
|
63
|
+
puts "Waiting #{time} seconds..."
|
64
|
+
Kernel.sleep seconds
|
65
|
+
end
|
66
|
+
|
67
|
+
# Alias for sleep.
|
68
|
+
alias :wait :sleep
|
69
|
+
|
70
|
+
# Prompt the user for the value of a given property matching a pattern.
|
71
|
+
#
|
72
|
+
# - message: message to print at prompt. Should include a description
|
73
|
+
# of the expected pattern.
|
74
|
+
# - property: the name of the property to set.
|
75
|
+
# - default: default value if user doesn't type anything. Written
|
76
|
+
# into square brakets after prompt message. Optional.
|
77
|
+
# - pattern: a Ruby pattern for prompted value. If this pattern is not
|
78
|
+
# matched, this task will prompt again. Optional, if no pattern is
|
79
|
+
# given, any value is accepted.
|
80
|
+
# - error: the error message to print when pattern is not matched.
|
81
|
+
# - attempts: number of allowed attempts. Optional, defaults to 0, which
|
82
|
+
# means an unlimited number of attempts.
|
83
|
+
#
|
84
|
+
# Example
|
85
|
+
#
|
86
|
+
# - prompt:
|
87
|
+
# message: "Enter your age"
|
88
|
+
# property: "age"
|
89
|
+
# default: 18
|
90
|
+
# pattern: "^\\d+$"
|
91
|
+
# error: "Age must be a positive integer"
|
92
|
+
def prompt(params)
|
93
|
+
params_desc = {
|
94
|
+
:message => { :mandatory => true, :type => :string },
|
95
|
+
:property => { :mandatory => true, :type => :string },
|
96
|
+
:default => { :mandatory => false, :type => :string },
|
97
|
+
:pattern => { :mandatory => false, :type => :string },
|
98
|
+
:error => { :mandatory => false, :type => :string },
|
99
|
+
:attempts => { :mandatory => false, :type => :integer, :default => 0 }
|
100
|
+
}
|
101
|
+
check_parameters(params, params_desc)
|
102
|
+
message = params[:message]
|
103
|
+
property = params[:property]
|
104
|
+
default = params[:default]
|
105
|
+
pattern = params[:pattern]
|
106
|
+
error = params[:error]
|
107
|
+
attempts = params[:attempts]
|
108
|
+
message << " [#{default}]" if default
|
109
|
+
message << ':'
|
110
|
+
ok = false
|
111
|
+
nb_attempts = 1
|
112
|
+
while not (ok or (nb_attempts > attempts and attempts != 0))
|
113
|
+
puts message
|
114
|
+
value = gets.strip
|
115
|
+
value = default if default and value.length == 0
|
116
|
+
if pattern
|
117
|
+
if value =~ /#{pattern}/
|
118
|
+
ok = true
|
119
|
+
elsif error
|
120
|
+
puts error
|
121
|
+
end
|
122
|
+
else
|
123
|
+
ok = true
|
124
|
+
end
|
125
|
+
nb_attempts += 1
|
126
|
+
end
|
127
|
+
error "Failed to obtain a matching prompt" if not ok
|
128
|
+
@build.context.set_property(property, value)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Get a given URL and store its content in a given file. Parameters
|
132
|
+
# is a Hash with following entries:
|
133
|
+
#
|
134
|
+
# - url: the URL to get.
|
135
|
+
# - dest: destination file. Optional, defaults to retrieved file name
|
136
|
+
# in current directory. If destination is a directory, file is saved
|
137
|
+
# in destination directory with the name of the retrieved file.
|
138
|
+
# - limit: the redirections limit. Optional, defaults to 10.
|
139
|
+
#
|
140
|
+
# Example
|
141
|
+
#
|
142
|
+
# - get:
|
143
|
+
# url: http://rubyforge.org/frs/download.php/22185/bee-0.4.0.zip
|
144
|
+
def get(parameters)
|
145
|
+
params_desc = {
|
146
|
+
:url => { :mandatory => true, :type => :string },
|
147
|
+
:dest => { :mandatory => false, :type => :string },
|
148
|
+
:limit => { :mandatory => false, :type => :integer, :default => 10 }
|
149
|
+
}
|
150
|
+
check_parameters(parameters, params_desc)
|
151
|
+
url = parameters[:url]
|
152
|
+
dest = parameters[:dest]
|
153
|
+
if not dest
|
154
|
+
destination = File.basename(url)
|
155
|
+
elsif File.directory?(dest)
|
156
|
+
destination = File.join(dest, File.basename(url))
|
157
|
+
else
|
158
|
+
destination = dest
|
159
|
+
end
|
160
|
+
limit = parameters[:limit]
|
161
|
+
puts "Getting URL '#{url}'..."
|
162
|
+
begin
|
163
|
+
content = Util::fetch(url, limit)
|
164
|
+
rescue Exception
|
165
|
+
error "Error getting URL: #{$!}"
|
166
|
+
end
|
167
|
+
todir = File.dirname(destination)
|
168
|
+
begin
|
169
|
+
FileUtils.makedirs(todir) if not File.exists?(todir)
|
170
|
+
File.open(destination, 'w') { |file| file.write(content) }
|
171
|
+
rescue Exception
|
172
|
+
error "Error saving file: #{$!}"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
######################################################################
|
177
|
+
# FILE RELATED TASKS #
|
178
|
+
######################################################################
|
179
|
+
|
46
180
|
# Print contents of a given file on the console. Parameter is the name
|
47
181
|
# of the file to output, as a String.
|
48
182
|
#
|
@@ -50,203 +184,609 @@ module Bee
|
|
50
184
|
#
|
51
185
|
# - cat: "doc/welcome-message.txt"
|
52
186
|
def cat(file)
|
53
|
-
|
54
|
-
error "
|
55
|
-
|
56
|
-
File.exists?(file) or File.directory?(file)
|
187
|
+
error "Parameter must be a string" unless file.kind_of?(String)
|
188
|
+
error "File '#{file}' not a regular file or not readable" unless
|
189
|
+
File.file?(file) and File.readable?(file)
|
57
190
|
puts File.read(file).strip
|
58
191
|
end
|
59
|
-
|
192
|
+
|
60
193
|
# Change working directory. This change will persist for all tasks in
|
61
|
-
# the target
|
62
|
-
# directory
|
194
|
+
# the current target. Entering a new target, working directory will
|
195
|
+
# recover its default value, which is the directory of the build file
|
196
|
+
# (or property 'base'). Parameter is a String with directory to change
|
197
|
+
# to.
|
63
198
|
#
|
64
199
|
# Example
|
65
200
|
#
|
66
201
|
# - cd: "build"
|
67
202
|
def cd(dir)
|
68
|
-
|
69
|
-
error "cd parameter
|
203
|
+
error "cd parameter must be a string" unless dir.kind_of?(String)
|
204
|
+
error "cd parameter must be a readable existing directory" unless
|
205
|
+
File.directory?(dir) and File.executable?(dir)
|
206
|
+
puts "Changing directory to '#{dir}'"
|
70
207
|
Dir.chdir(dir)
|
71
208
|
end
|
72
|
-
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
209
|
+
|
210
|
+
# Put working directory in a given property. Parameter is the name of
|
211
|
+
# the property to write current directory into.
|
212
|
+
#
|
213
|
+
# Example
|
214
|
+
#
|
215
|
+
# - pwd: current_dir
|
216
|
+
def pwd(property)
|
217
|
+
error "pwd parameter must be a string" unless property.kind_of?(String)
|
218
|
+
pwd = FileUtils.pwd
|
219
|
+
@build.context.set_property(property, pwd)
|
220
|
+
end
|
221
|
+
|
222
|
+
# Make a symbolic link from a source file to a destination one.
|
223
|
+
# Parameter is a Hash with following entries:
|
224
|
+
#
|
225
|
+
# - old: source of the link, as a glob. If there are more than one
|
226
|
+
# file to link, this task will make links 'new/file' for each file
|
227
|
+
# of the glob.
|
228
|
+
# - new: destination of the link.
|
229
|
+
#
|
230
|
+
# Example
|
231
|
+
#
|
232
|
+
# - ln:
|
233
|
+
# old: /usr/local
|
234
|
+
# new: /opt
|
235
|
+
#
|
236
|
+
# Note:
|
237
|
+
#
|
238
|
+
# This task is not implemented under Windows.
|
239
|
+
def ln(parameters)
|
240
|
+
params_desc = {
|
241
|
+
:old => { :mandatory => true, :type => :string },
|
242
|
+
:new => { :mandatory => true, :type => :string }
|
243
|
+
}
|
244
|
+
check_parameters(parameters, params_desc)
|
245
|
+
old = parameters[:old]
|
246
|
+
new = parameters[:new]
|
247
|
+
files = Dir.glob(old)
|
248
|
+
files = files.first if files.length == 1
|
249
|
+
puts "Linking #{files.length} file(s) to '#{new}'"
|
250
|
+
begin
|
251
|
+
FileUtils.ln_s(files, new)
|
252
|
+
rescue
|
253
|
+
error "Error making the link: #{$!}"
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# Alias for ln.
|
258
|
+
alias :link :ln
|
259
|
+
|
260
|
+
# Change permissions for a set of files. Parameters is a Hash with
|
261
|
+
# following entries:
|
262
|
+
#
|
263
|
+
# - files: files to change permissions for, as a glob.
|
264
|
+
# - mode: permissons as an Unix integer (such as 0644 or 0755). Note that
|
265
|
+
# numbers starting with 0 are considered octal, with 0x, they are
|
266
|
+
# supposed to be hexa and in base 10 otherwise.
|
267
|
+
# - recursive: tells if should process directories recursively.
|
268
|
+
# Optional, defaults to 'false'.
|
269
|
+
#
|
270
|
+
# Example:
|
271
|
+
#
|
272
|
+
# - chmod:
|
273
|
+
# files: /usr/local/bin/*
|
274
|
+
# mode: 0755
|
275
|
+
#
|
276
|
+
# Note:
|
277
|
+
#
|
278
|
+
# This task is not implemented under Windows.
|
279
|
+
def chmod(parameters)
|
280
|
+
params_desc = {
|
281
|
+
:files => { :mandatory => true, :type => :string_or_array },
|
282
|
+
:mode => { :mandatory => true, :type => :integer },
|
283
|
+
:recursive => { :mandatory => false, :type => :boolean, :default => false }
|
284
|
+
}
|
285
|
+
check_parameters(parameters, params_desc)
|
286
|
+
files = parameters[:files]
|
287
|
+
mode = parameters[:mode]
|
288
|
+
recursive = parameters[:recursive]
|
289
|
+
files = Dir.glob(files)
|
290
|
+
if files.length > 0
|
291
|
+
puts "Changing permissions for #{files.length} file(s) to '#{mode}'"
|
292
|
+
begin
|
293
|
+
if recursive
|
294
|
+
FileUtils.chmod_R(mode, files)
|
295
|
+
else
|
296
|
+
FileUtils.chmod(mode, files)
|
297
|
+
end
|
298
|
+
rescue
|
299
|
+
error "Error changing permissions: #{$!}"
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
# Change owner and group for a set of files. Parameters is a Hash with
|
305
|
+
# following entries:
|
306
|
+
#
|
307
|
+
# - files: files to change owner for, as a glob.
|
308
|
+
# - user: the user to change for, may be a name or an ID (integer). If
|
309
|
+
# not set, the user is not changed.
|
310
|
+
# - group: the group to change for, may be a name or an ID (integer). If
|
311
|
+
# not set, the group is not changed.
|
312
|
+
# - recursive: tells if should process directories recursively.
|
313
|
+
# Optional, defaults to 'false'.
|
314
|
+
#
|
315
|
+
# Example:
|
316
|
+
#
|
317
|
+
# - chown:
|
318
|
+
# files: /home/casa
|
319
|
+
# user: casa
|
320
|
+
# group: staff
|
321
|
+
# recursive: true
|
322
|
+
#
|
323
|
+
# Note:
|
324
|
+
#
|
325
|
+
# This task is not implemented under Windows.
|
326
|
+
def chown(parameters)
|
327
|
+
params_desc = {
|
328
|
+
:files => { :mandatory => true, :type => :string_or_array },
|
329
|
+
:user => { :mandatory => false, :type => :string_or_integer },
|
330
|
+
:group => { :mandatory => false, :type => :string_or_integer },
|
331
|
+
:recursive => { :mandatory => false, :type => :boolean, :default => false }
|
332
|
+
}
|
333
|
+
check_parameters(parameters, params_desc)
|
334
|
+
files = parameters['files']
|
335
|
+
user = parameters['user']
|
336
|
+
group = parameters['group']
|
337
|
+
recursive = parameters['recursive']
|
338
|
+
files = Dir.glob(files)
|
339
|
+
if files.length > 0
|
340
|
+
puts "Changing owner of #{files.length} file(s) to '#{user}/#{group}'"
|
341
|
+
begin
|
342
|
+
if recursive
|
343
|
+
FileUtils.chown_R(user, group, files)
|
344
|
+
else
|
345
|
+
FileUtils.chown(user, group, files)
|
346
|
+
end
|
347
|
+
rescue
|
348
|
+
error "Error changing owner: #{$!}"
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
# Make a directory, and parent directories if necessary. Doesn't
|
354
|
+
# complain if directory already exists. Parameter is directory to
|
355
|
+
# create as a String or a list of directories as an Array of Strings.
|
76
356
|
#
|
77
357
|
# Example
|
78
358
|
#
|
79
359
|
# - mkdir: "foo/bar"
|
80
|
-
# - mkdir: ["foo", "bar"]
|
81
360
|
def mkdir(dirs)
|
82
|
-
require 'fileutils'
|
83
|
-
dirs = dirs
|
84
361
|
error "mkdir parameter must a String or an array of Strings" unless
|
85
|
-
|
362
|
+
dirs.kind_of?(String) or dirs.kind_of?(Array)
|
86
363
|
for dir in dirs
|
87
364
|
error "mkdir parameter must a String or an array of Strings" unless
|
88
|
-
|
89
|
-
|
365
|
+
dir.kind_of?(String)
|
366
|
+
puts "Creating directory '#{dir}'"
|
367
|
+
begin
|
368
|
+
FileUtils.makedirs(dir)
|
369
|
+
rescue
|
370
|
+
error "Error creating directory '#{dir}': #{$!}"
|
371
|
+
end
|
90
372
|
end
|
91
373
|
end
|
92
|
-
|
374
|
+
|
93
375
|
# Copy files or directories to destination file or directory. Parameter
|
94
376
|
# is a Hash with following entries:
|
95
377
|
#
|
96
|
-
# -
|
97
|
-
#
|
98
|
-
# - excludes: glob or list of globs for source files or directories to
|
99
|
-
# exclude.
|
378
|
+
# - src: glob or list of globs for source files or directories to copy.
|
379
|
+
# Included source directories are copied recursively.
|
100
380
|
# - dest: destination file or directory.
|
101
381
|
#
|
102
382
|
# Example
|
103
383
|
#
|
104
384
|
# - cp:
|
105
|
-
#
|
106
|
-
# excludes: ["**/*.bmp", "**/*.psd"]
|
385
|
+
# src: "img/*"
|
107
386
|
# dest: :doc
|
108
387
|
def cp(params)
|
109
|
-
require 'fileutils'
|
110
388
|
params_desc = {
|
111
|
-
|
112
|
-
|
113
|
-
'dest' => :mandatory
|
389
|
+
:src => { :mandatory => true, :type => :string_or_array },
|
390
|
+
:dest => { :mandatory => true, :type => :string }
|
114
391
|
}
|
115
|
-
|
116
|
-
|
117
|
-
excludes = params['excludes']
|
392
|
+
check_parameters(params, params_desc)
|
393
|
+
src = params['src']
|
118
394
|
dest = params['dest']
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
395
|
+
src = Array(src).map { |s| Dir.glob(s) }.flatten.uniq
|
396
|
+
src = src.first if src.length == 1
|
397
|
+
if src.kind_of?(Array)
|
398
|
+
nb_copies = src.length
|
399
|
+
else
|
400
|
+
nb_copies = 1
|
401
|
+
end
|
402
|
+
puts "Copying #{nb_copies} file(s) to '#{dest}'"
|
403
|
+
begin
|
404
|
+
FileUtils.cp_r(src, dest)
|
405
|
+
rescue
|
406
|
+
error "Error copying file(s): #{$!}"
|
407
|
+
end
|
123
408
|
end
|
124
|
-
|
125
|
-
#
|
126
|
-
#
|
409
|
+
|
410
|
+
# Moves files or directories to destination file or directory. Parameter
|
411
|
+
# is a Hash with following entries:
|
127
412
|
#
|
128
|
-
# -
|
129
|
-
#
|
130
|
-
#
|
131
|
-
# - dest: file or directory to move file(s) to.
|
413
|
+
# - src: glob or list of globs for source files or directories to move.
|
414
|
+
# Included source directories are moved recursively.
|
415
|
+
# - dest: destination file or directory.
|
132
416
|
#
|
133
417
|
# Example
|
134
418
|
#
|
135
|
-
# - mv:
|
419
|
+
# - mv:
|
420
|
+
# src: "**/*~"
|
421
|
+
# dest: :trash
|
136
422
|
def mv(params)
|
137
|
-
require 'fileutils'
|
138
423
|
params_desc = {
|
139
|
-
|
140
|
-
|
141
|
-
'dest' => :mandatory
|
424
|
+
:src => { :mandatory => true, :type => :string_or_array },
|
425
|
+
:dest => { :mandatory => true, :type => :string }
|
142
426
|
}
|
143
|
-
|
144
|
-
|
145
|
-
excludes = params['excludes']
|
427
|
+
check_parameters(params, params_desc)
|
428
|
+
src = params['src']
|
146
429
|
dest = params['dest']
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
430
|
+
src = Array(src).map { |s| Dir.glob(s) }.flatten.uniq
|
431
|
+
src = src.first if src.length == 1
|
432
|
+
if src.kind_of?(Array)
|
433
|
+
nb_moves = src.length
|
434
|
+
else
|
435
|
+
nb_moves = 1
|
436
|
+
end
|
437
|
+
puts "Moving #{nb_moves} file(s) to '#{dest}'"
|
438
|
+
begin
|
439
|
+
FileUtils.mv(src, dest)
|
440
|
+
rescue
|
441
|
+
error "Error moving file(s): #{$!}"
|
442
|
+
end
|
151
443
|
end
|
152
|
-
|
444
|
+
|
445
|
+
# Copy filtered files. Parameter is a hash with following entries:
|
446
|
+
#
|
447
|
+
# - root: root directory for files to copy. Optional, defaults to current
|
448
|
+
# directory.
|
449
|
+
# - includes: list of globs for files to copy. Optional, defaults to
|
450
|
+
# '**/*' to include all files recursively.
|
451
|
+
# - excludes: list of globs for files to exclude from copy. Optional,
|
452
|
+
# default to nil to exclude no file.
|
453
|
+
# - dotmatch: tells if joker matches dot files. Optional, defaults to
|
454
|
+
# false.
|
455
|
+
# - flatten: tells if included files should be copied in destination
|
456
|
+
# directory, ignoring their subdirectory. Optional, defaults to false.
|
457
|
+
#
|
458
|
+
# Example:
|
459
|
+
#
|
460
|
+
# To copy all files from directory 'src', except those living in 'CVS'
|
461
|
+
# directories, into directory 'destination', you could write:
|
462
|
+
#
|
463
|
+
# - copy:
|
464
|
+
# root: src
|
465
|
+
# includes: **/*
|
466
|
+
# excludes: **/CVS/**/*
|
467
|
+
# dest: destination
|
468
|
+
#
|
469
|
+
# Note: this task only deals with files. Thus, 'includes' and 'excludes'
|
470
|
+
# globs should be ones for files.
|
471
|
+
def copy(params)
|
472
|
+
# check parameters and set default values
|
473
|
+
params_desc = {
|
474
|
+
:root => { :mandatory => false, :type => :string, :default => '.' },
|
475
|
+
:includes => { :mandatory => false, :type => :string_or_array },
|
476
|
+
:excludes => { :mandatory => false, :type => :string_or_array },
|
477
|
+
:dest => { :mandatory => true, :type => :string },
|
478
|
+
:flatten => { :mandatory => false, :type => :boolean, :default => false },
|
479
|
+
:dotmatch => { :mandatory => false, :type => :boolean, :default => false }
|
480
|
+
}
|
481
|
+
check_parameters(params, params_desc)
|
482
|
+
root = params[:root]
|
483
|
+
includes = params[:includes]
|
484
|
+
excludes = params[:excludes]
|
485
|
+
dest = params[:dest]
|
486
|
+
flatten = params[:flatten]
|
487
|
+
dotmatch = params[:dotmatch]
|
488
|
+
error "copy 'root' parameter must be an existing directory" unless
|
489
|
+
File.exists?(root) and File.directory?(root)
|
490
|
+
error "copy 'dest' parameter must be an existing directory" unless
|
491
|
+
File.exists?(dest) and File.directory?(dest)
|
492
|
+
# select files and copy
|
493
|
+
files = filter_files(includes, excludes, root, dotmatch)
|
494
|
+
puts "Copying #{files.length} file(s) to '#{dest}'"
|
495
|
+
for file in files
|
496
|
+
from_file = File.join(root, file)
|
497
|
+
if flatten
|
498
|
+
to_file = File.join(dest, File.basename(file))
|
499
|
+
else
|
500
|
+
to_file = File.join(dest, file)
|
501
|
+
end
|
502
|
+
to_dir = File.dirname(to_file)
|
503
|
+
FileUtils.makedirs(to_dir) if not File.exists?(to_dir)
|
504
|
+
FileUtils.cp(from_file, to_file)
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
508
|
+
# Move filtered files. Parameter is a hash with following entries:
|
509
|
+
#
|
510
|
+
# - root: root directory for files to move. Optional, defaults to
|
511
|
+
# current directory.
|
512
|
+
# - includes: list of globs for files to move. Optional, defaults to
|
513
|
+
# '**/*' to include all files recursively.
|
514
|
+
# - excludes: list of globs for files to exclude from move. Optional,
|
515
|
+
# default to nil to exclude no file.
|
516
|
+
# - flatten: tells if included files should be moved to destination
|
517
|
+
# directory, ignoring their subdirectory. Optional, defaults to false.
|
518
|
+
# - dotmatch: tells if joker matches dot files. Optional, defaults to
|
519
|
+
# false.
|
520
|
+
#
|
521
|
+
# Example:
|
522
|
+
#
|
523
|
+
# To move all files from directory 'src', except those living in 'CVS'
|
524
|
+
# directories, into directory 'destination', you could write:
|
525
|
+
#
|
526
|
+
# - move:
|
527
|
+
# root: src
|
528
|
+
# includes: **/*
|
529
|
+
# excludes: **/CVS/**/*
|
530
|
+
# dest: destination
|
531
|
+
#
|
532
|
+
# Note: this task only deals with files. Thus, 'includes' and 'excludes'
|
533
|
+
# globs should be ones for files and directories from root will not
|
534
|
+
# be affected by this task.
|
535
|
+
def move(params)
|
536
|
+
# check parameters and set default values
|
537
|
+
params_desc = {
|
538
|
+
:root => { :mandatory => false, :type => :string, :default => '.' },
|
539
|
+
:includes => { :mandatory => false, :type => :string_or_array },
|
540
|
+
:excludes => { :mandatory => false, :type => :string_or_array },
|
541
|
+
:dest => { :mandatory => true, :type => :string },
|
542
|
+
:flatten => { :mandatory => false, :type => :boolean, :default => false },
|
543
|
+
:dotmatch => { :mandatory => false, :type => :boolean, :default => false }
|
544
|
+
}
|
545
|
+
check_parameters(params, params_desc)
|
546
|
+
root = params[:root]
|
547
|
+
includes = params[:includes]
|
548
|
+
excludes = params[:excludes]
|
549
|
+
dest = params[:dest]
|
550
|
+
flatten = params[:flatten]
|
551
|
+
dotmatch = params[:dotmatch]
|
552
|
+
error "move 'root' parameter must be an existing directory" unless
|
553
|
+
File.exists?(root) and File.directory?(root)
|
554
|
+
error "move 'dest' parameter must be an existing directory" unless
|
555
|
+
File.exists?(dest) and File.directory?(dest)
|
556
|
+
# select files and make move
|
557
|
+
files = filter_files(includes, excludes, root, dotmatch)
|
558
|
+
puts "Moving #{files.length} file(s) to '#{dest}'"
|
559
|
+
for file in files
|
560
|
+
from_file = File.join(root, file)
|
561
|
+
if flatten
|
562
|
+
to_file = File.join(dest, File.basename(file))
|
563
|
+
else
|
564
|
+
to_file = File.join(dest, file)
|
565
|
+
end
|
566
|
+
to_dir = File.dirname(to_file)
|
567
|
+
FileUtils.makedirs(to_dir) if not File.exists?(to_dir)
|
568
|
+
FileUtils.mv(from_file, to_file)
|
569
|
+
end
|
570
|
+
end
|
571
|
+
|
153
572
|
# Delete files for a given glob or list of globs. Parameter is a glob or
|
154
|
-
# list of globs for files to delete.
|
573
|
+
# list of globs for files to delete. This task will raise an error if
|
574
|
+
# told to delete a directory. Use task 'rmrf' to do so.
|
155
575
|
#
|
156
576
|
# Example
|
157
577
|
#
|
158
|
-
# - rm: "**/*.bak"
|
159
578
|
# - rm: ["**/*~", "**/.DS_Store"]
|
160
579
|
def rm(globs)
|
161
|
-
require 'fileutils'
|
162
|
-
globs = globs
|
163
580
|
error "rm parameter is a String or Array of Strings" unless
|
164
581
|
globs.kind_of?(String) or globs.kind_of?(Array)
|
165
582
|
for glob in globs
|
166
583
|
error "rm parameter is a String or Array of Strings" unless
|
167
584
|
glob.kind_of?(String)
|
168
585
|
files = Dir.glob(glob)
|
586
|
+
size = (files.kind_of?(Array) ? files.size : 1)
|
587
|
+
puts "Deleting #{size} file(s)" if files.length > 0
|
169
588
|
for file in files
|
170
|
-
|
589
|
+
begin
|
590
|
+
FileUtils.rm(file)
|
591
|
+
rescue
|
592
|
+
error "Error deleting files: #{$!}"
|
593
|
+
end
|
171
594
|
end
|
172
595
|
end
|
173
596
|
end
|
174
|
-
|
175
|
-
# Delete directories recursively. Parameter is a
|
176
|
-
# directories to delete.
|
597
|
+
|
598
|
+
# Delete files and directories recursively. Parameter is a glob or list
|
599
|
+
# of globs for files and directories to delete.
|
177
600
|
#
|
178
601
|
# Example
|
179
602
|
#
|
180
|
-
# -
|
181
|
-
def
|
182
|
-
|
183
|
-
|
184
|
-
error "rmdir parameter is a String or an Array of Strings" unless
|
603
|
+
# - rmrf: :build
|
604
|
+
def rmrf(globs)
|
605
|
+
globs = [globs] if globs.kind_of?(String)
|
606
|
+
error "rmrf parameter is a String or an Array of Strings" unless
|
185
607
|
globs.kind_of?(String) or globs.kind_of?(Array)
|
186
608
|
for glob in globs
|
187
|
-
error "
|
609
|
+
error "rmrf parameter is a String or an Array of Strings" unless
|
188
610
|
glob.kind_of?(String)
|
189
611
|
dirs = Dir.glob(glob)
|
612
|
+
size = (dirs.kind_of?(Array) ? dirs.size : 1)
|
613
|
+
puts "Deleting #{size} directory(ies)" if dirs.length > 0
|
190
614
|
for dir in dirs
|
191
|
-
|
615
|
+
begin
|
616
|
+
FileUtils.rm_rf(dir)
|
617
|
+
rescue
|
618
|
+
error "Error deleting directory(ies): #{$!}"
|
619
|
+
end
|
192
620
|
end
|
193
621
|
end
|
194
622
|
end
|
195
|
-
|
623
|
+
|
624
|
+
# Alias for rmrf.
|
625
|
+
alias :rmdir :rmrf
|
626
|
+
|
627
|
+
# Update modification time and access time of files in a list. Files
|
628
|
+
# are created if they don't exist. Parameter is a glob or list of
|
629
|
+
# globs for files to touch.
|
630
|
+
#
|
631
|
+
# Example
|
632
|
+
#
|
633
|
+
# - touch: '#{target}/classes/**/*.class'
|
634
|
+
def touch(globs)
|
635
|
+
globs = [globs] if globs.kind_of?(String)
|
636
|
+
error "touch parameter is a String or an Array of Strings" unless
|
637
|
+
globs.kind_of?(String) or globs.kind_of?(Array)
|
638
|
+
files = []
|
639
|
+
for glob in globs
|
640
|
+
error "touch parameter is a String or an Array of Strings" unless
|
641
|
+
glob.kind_of?(String)
|
642
|
+
new_files = Dir.glob(glob)
|
643
|
+
if new_files.length == 0
|
644
|
+
files << glob
|
645
|
+
else
|
646
|
+
files += new_files
|
647
|
+
end
|
648
|
+
end
|
649
|
+
files.uniq!
|
650
|
+
size = (files.kind_of?(Array) ? files.size : 1)
|
651
|
+
puts "Touching #{size} file(s)" if size > 0
|
652
|
+
begin
|
653
|
+
FileUtils.touch(files)
|
654
|
+
rescue
|
655
|
+
error "Error touching file(s): #{$!}"
|
656
|
+
end
|
657
|
+
end
|
658
|
+
|
196
659
|
# Find files for a glob or list of globs and store list in a property.
|
197
660
|
# Parameter is a Hash with entries:
|
198
661
|
#
|
199
|
-
# -
|
662
|
+
# - root: root directory for file search. Defaults to '.' (current
|
663
|
+
# directory).
|
664
|
+
# - includes: glob or list of globs for files to look for. Defaults to
|
665
|
+
# '**/*' to include all files recursively.
|
200
666
|
# - excludes: glob or list of globs for files to exclude from search.
|
667
|
+
# Defaults to nil to exclude no file.
|
668
|
+
# - dotmatch: tells if joker matches dot files. Optional, defaults to
|
669
|
+
# false.
|
201
670
|
# - property: name of the property to set.
|
671
|
+
# - join: a character used to join the list in a string. Defaults
|
672
|
+
# to nil so that list is not joined.
|
202
673
|
#
|
203
674
|
# Example
|
675
|
+
#
|
676
|
+
# To find all PNG in files in 'img' directory, and store the list in
|
677
|
+
# property image_files, one could write:
|
204
678
|
#
|
205
|
-
# - find: { includes: "**/*.rb", property: "rb_files_to_check" }
|
206
679
|
# - find:
|
207
|
-
#
|
208
|
-
#
|
209
|
-
#
|
210
|
-
def find(
|
680
|
+
# root: "img"
|
681
|
+
# includes: "**/*.png"
|
682
|
+
# property: "image_files"
|
683
|
+
def find(params)
|
211
684
|
params_desc = {
|
212
|
-
|
213
|
-
|
214
|
-
|
685
|
+
:root => { :mandatory => false, :type => :string, :default => '.' },
|
686
|
+
:includes => { :mandatory => false, :type => :string_or_array },
|
687
|
+
:excludes => { :mandatory => false, :type => :string_or_array },
|
688
|
+
:property => { :mandatory => true, :type => :string },
|
689
|
+
:dotmatch => { :mandatory => false, :type => :boolean, :default => false },
|
690
|
+
:join => { :mandatory => false, :type => :string }
|
215
691
|
}
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
692
|
+
check_parameters(params, params_desc)
|
693
|
+
root = params[:root]
|
694
|
+
includes = params[:includes]
|
695
|
+
excludes = params[:excludes]
|
696
|
+
property = params[:property]
|
697
|
+
dotmatch = params[:dotmatch]
|
698
|
+
join = params[:join]
|
699
|
+
files = filter_files(includes, excludes, root, dotmatch)
|
700
|
+
if join
|
701
|
+
files = files.join(join)
|
702
|
+
end
|
221
703
|
@build.context.set_property(property, files)
|
222
704
|
end
|
223
|
-
|
224
|
-
|
225
|
-
#
|
226
|
-
|
705
|
+
|
706
|
+
######################################################################
|
707
|
+
# RUBY RELATED TASKS #
|
708
|
+
######################################################################
|
709
|
+
|
710
|
+
# Tests a required library and prints an error message if import
|
711
|
+
# fails. Parameter is a Hash with entries:
|
712
|
+
#
|
713
|
+
# - library: required library (as in require call).
|
714
|
+
# - message: error message to print if require fails.
|
715
|
+
#
|
227
716
|
# Example
|
717
|
+
#
|
718
|
+
# - required:
|
719
|
+
# library: foo
|
720
|
+
# message: >
|
721
|
+
# Library foo must be installed (gem install foo) to run
|
722
|
+
# task bar.
|
723
|
+
def required(params)
|
724
|
+
require 'rubygems'
|
725
|
+
require 'rubygems/gem_runner'
|
726
|
+
params_desc = {
|
727
|
+
:library => { :mandatory => true, :type => :string },
|
728
|
+
:message => { :mandatory => true, :type => :string }
|
729
|
+
}
|
730
|
+
check_parameters(params, params_desc)
|
731
|
+
library = params[:library]
|
732
|
+
message = params[:message]
|
733
|
+
if Gem::RubyGemsVersion < '1.3.0'
|
734
|
+
begin
|
735
|
+
Gem::activate(library, false)
|
736
|
+
available = true
|
737
|
+
rescue LoadError
|
738
|
+
available = false
|
739
|
+
end
|
740
|
+
else
|
741
|
+
available = Gem::available?(library)
|
742
|
+
end
|
743
|
+
error message if not available
|
744
|
+
end
|
745
|
+
|
746
|
+
# Run Ruby unit tests listed as a glob or list of globs in a given
|
747
|
+
# directory (that defaults to current one). Parameter is a Hash with
|
748
|
+
# following entries:
|
228
749
|
#
|
229
|
-
#
|
750
|
+
# - root: root directory for files to include. Defaults to current
|
751
|
+
# directory.
|
752
|
+
# - includes: glob or list of globs for unit test files to run.
|
753
|
+
# Defaults to '**/*' to include all files recursively.
|
754
|
+
# - excludes: glob or list of globs for unit test files to exclude.
|
755
|
+
# Defaults to nil to exclude no file.
|
756
|
+
# - dotmatch: tells if joker matches dot files. Optional, defaults to
|
757
|
+
# false.
|
758
|
+
# - dir: directory where to run unit tests.
|
230
759
|
#
|
231
|
-
#
|
760
|
+
# Example
|
232
761
|
#
|
233
|
-
#
|
234
|
-
|
762
|
+
# - find:
|
763
|
+
# root: :test
|
764
|
+
# includes: "**/tc_*.rb"
|
765
|
+
# dir: "test"
|
766
|
+
def test(params)
|
235
767
|
require 'test/unit'
|
236
768
|
require 'test/unit/testresult'
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
769
|
+
params_desc = {
|
770
|
+
:root => { :mandatory => false, :type => :string },
|
771
|
+
:includes => { :mandatory => true, :type => :string },
|
772
|
+
:excludes => { :mandatory => false, :type => :string },
|
773
|
+
:dotmatch => { :mandatory => false, :type => :boolean, :default => false },
|
774
|
+
:dir => { :mandatory => false, :type => :string, :default => '.' }
|
775
|
+
}
|
776
|
+
check_parameters(params, params_desc)
|
777
|
+
root = params[:root]
|
778
|
+
includes = params[:includes]
|
779
|
+
excludes = params[:excludes]
|
780
|
+
dotmatch = params[:dotmatch]
|
781
|
+
dir = params[:dir]
|
782
|
+
files = filter_files(includes, excludes, root, dotmatch)
|
246
783
|
for file in files
|
247
784
|
load file
|
248
785
|
end
|
249
|
-
|
786
|
+
size = (files.kind_of?(Array) ? files.size : 1)
|
787
|
+
puts "Running #{size} unit test(s)"
|
788
|
+
ok = Test::Unit::AutoRunner.run(false, dir)
|
789
|
+
error "Tests failed" if not ok
|
250
790
|
end
|
251
791
|
|
252
792
|
# Run an ERB file or source in bee context and store result in a file or
|
@@ -267,34 +807,32 @@ module Bee
|
|
267
807
|
#
|
268
808
|
# <p>Hello <%= foo %>!</p>
|
269
809
|
def erb(params)
|
270
|
-
require 'erb'
|
271
|
-
# check parameters
|
272
810
|
params_desc = {
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
811
|
+
:source => { :mandatory => false, :type => :string },
|
812
|
+
:src => { :mandatory => false, :type => :string },
|
813
|
+
:dest => { :mandatory => false, :type => :string },
|
814
|
+
:property => { :mandatory => false, :type => :string }
|
277
815
|
}
|
278
|
-
|
279
|
-
source
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
error "erb 'src' parameter must be a String" unless
|
284
|
-
src.kind_of?(String) or src == nil
|
285
|
-
dest = params['dest']
|
286
|
-
error "erb 'dest' parameter must be a String" unless
|
287
|
-
dest.kind_of?(String) or dest == nil
|
288
|
-
property = params['property']
|
289
|
-
error "erb 'property' parameter must be a String" unless
|
290
|
-
property.kind_of?(String) or property == nil
|
816
|
+
check_parameters(params, params_desc)
|
817
|
+
source = params[:source]
|
818
|
+
src = params[:src]
|
819
|
+
dest = params[:dest]
|
820
|
+
property = params[:property]
|
291
821
|
error "Must pass one of 'source' or 'src' parameters to erb task" if
|
292
822
|
not source and not src
|
293
823
|
error "Must pass one of 'dest' or 'property' parameters to erb task" if
|
294
824
|
not dest and not property
|
825
|
+
error "erb src file '#{src}' not found" if src and
|
826
|
+
(not File.exists?(src) or not File.file?(src) or
|
827
|
+
not File.readable?(src))
|
295
828
|
# load ERB source
|
296
829
|
erb_source = source||File.read(src)
|
297
830
|
template = ERB.new(erb_source)
|
831
|
+
if src
|
832
|
+
puts "Processing ERB '#{src}'"
|
833
|
+
else
|
834
|
+
puts "Processing ERB"
|
835
|
+
end
|
298
836
|
begin
|
299
837
|
result = template.result(@build.context.context_binding)
|
300
838
|
rescue
|
@@ -302,7 +840,11 @@ module Bee
|
|
302
840
|
end
|
303
841
|
# write result in file or set property
|
304
842
|
if dest
|
305
|
-
|
843
|
+
begin
|
844
|
+
File.open(dest, 'w') { |file| file.write(result) }
|
845
|
+
rescue
|
846
|
+
error "Error writing ERB processing result in file: #{$!}"
|
847
|
+
end
|
306
848
|
else
|
307
849
|
@build.context.set_property(property, result)
|
308
850
|
end
|
@@ -312,106 +854,226 @@ module Bee
|
|
312
854
|
# exclude and a destination directory. Parameter is a Hash with following
|
313
855
|
# entries:
|
314
856
|
#
|
315
|
-
# -
|
316
|
-
#
|
317
|
-
#
|
857
|
+
# - root: root directory for files to include. Defaults to current
|
858
|
+
# directory.
|
859
|
+
# - includes: glob or list of globs for files or directories to document.
|
860
|
+
# Defaults to '**/*' to include all files.
|
861
|
+
# - excludes: glob or list of globs for files or directories that should
|
862
|
+
# not be documented. Defaults to nil to exclude no file.
|
863
|
+
# - dotmatch: tells if joker matches dot files. Optional, defaults to
|
864
|
+
# false.
|
318
865
|
# - dest: destination directory for generated documentation.
|
319
866
|
# - options: additional options as a string or list of strings.
|
320
867
|
#
|
321
868
|
# Example
|
322
869
|
#
|
323
870
|
# - rdoc:
|
324
|
-
# includes: ["README", "LICENSE",
|
871
|
+
# includes: ["README", "LICENSE", "#{src}/**/*"]
|
325
872
|
# dest: :api
|
326
|
-
def rdoc(
|
873
|
+
def rdoc(params)
|
327
874
|
require 'rdoc/rdoc'
|
328
|
-
params_desc
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
875
|
+
params_desc= {
|
876
|
+
:root => { :mandatory => false, :type => :string },
|
877
|
+
:includes => { :mandatory => true, :type => :string_or_array },
|
878
|
+
:excludes => { :mandatory => false, :type => :string_or_array },
|
879
|
+
:dotmatch => { :mandatory => false, :type => :boolean, :default => false },
|
880
|
+
:dest => { :mandatory => true, :type => :string },
|
881
|
+
:options => { :mandatory => false, :type => :string_or_array }
|
333
882
|
}
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
files =
|
883
|
+
check_parameters(params, params_desc)
|
884
|
+
root = params[:root]
|
885
|
+
includes = params[:includes]
|
886
|
+
excludes = params[:excludes]
|
887
|
+
dotmatch = params[:dotmatch]
|
888
|
+
dest = params[:dest]
|
889
|
+
options = params[:options]
|
890
|
+
files = filter_files(includes, excludes, root, dotmatch)
|
342
891
|
command_line = ['-S', '-o', dest]
|
343
892
|
command_line << options if options
|
344
893
|
command_line += files
|
345
|
-
|
346
|
-
|
894
|
+
begin
|
895
|
+
rdoc = RDoc::RDoc.new
|
896
|
+
rdoc.document(command_line)
|
897
|
+
rescue
|
898
|
+
error "Error generating RDoc: #{$!}"
|
899
|
+
end
|
347
900
|
end
|
348
901
|
|
349
|
-
# Generate a Gem package
|
350
|
-
#
|
351
|
-
# command line tool).
|
902
|
+
# Generate a Gem package in current directory, named after the Gem name
|
903
|
+
# and version. Parameter is the name of the Gem description file.
|
352
904
|
#
|
353
905
|
# Example
|
354
906
|
#
|
355
|
-
# -
|
356
|
-
def
|
907
|
+
# - gem: :gem_spec
|
908
|
+
def gem(description)
|
357
909
|
require 'rubygems'
|
358
|
-
|
910
|
+
require 'rubygems/gem_runner'
|
911
|
+
error "gem parameter must be an existing file" if
|
912
|
+
not description.kind_of?(String) or not File.exists?(description)
|
359
913
|
arguments = ['build', description]
|
360
|
-
|
361
|
-
|
914
|
+
begin
|
915
|
+
Gem::GemRunner.new.run(arguments)
|
916
|
+
rescue Exception
|
917
|
+
error "Error generating Gem: #{$!}"
|
918
|
+
end
|
362
919
|
end
|
363
920
|
|
921
|
+
# Run another bee build file.
|
922
|
+
#
|
923
|
+
# - file: the build file to run, relative to current build file.
|
924
|
+
# Optional, defaults to 'build.yml'.
|
925
|
+
# - target: target or list of targets to run (default target if omitted).
|
926
|
+
# - properties: boolean (true or false) that tells if properties of
|
927
|
+
# current build file should be sent and overwrite those of target
|
928
|
+
# build. Properties modified in child build don't change in parent
|
929
|
+
# one. Defaults to false.
|
930
|
+
#
|
931
|
+
# Example
|
932
|
+
#
|
933
|
+
# - bee:
|
934
|
+
# file: "doc/build.yml"
|
935
|
+
# target: "pdf"
|
936
|
+
# properties: true
|
937
|
+
def bee(parameters)
|
938
|
+
# parse parameters
|
939
|
+
params_desc = {
|
940
|
+
:file => { :mandatory => false, :type => :string, :default => 'build.yml' },
|
941
|
+
:target => { :mandatory => false, :type => :string_or_array, :default => '' },
|
942
|
+
:properties => { :mandatory => false, :type => :boolean, :default => false }
|
943
|
+
}
|
944
|
+
check_parameters(parameters, params_desc)
|
945
|
+
file = parameters[:file]
|
946
|
+
target = parameters[:target]
|
947
|
+
properties = parameters[:properties]
|
948
|
+
# run target build
|
949
|
+
props = {}
|
950
|
+
if properties
|
951
|
+
for name in @build.context.properties
|
952
|
+
props[name] = @build.context.get_property(name)
|
953
|
+
end
|
954
|
+
end
|
955
|
+
begin
|
956
|
+
build = Bee::Build.load(file, false, props)
|
957
|
+
build.run(target, @build.listener.clone)
|
958
|
+
rescue
|
959
|
+
error "Error invoking build file '#{file}': #{$!}"
|
960
|
+
end
|
961
|
+
end
|
962
|
+
|
963
|
+
######################################################################
|
964
|
+
# ARCHIVE TASKS #
|
965
|
+
######################################################################
|
966
|
+
|
364
967
|
# Generate a ZIP archive. Parameter is a Hash with following entries:
|
365
968
|
#
|
969
|
+
# - root: root directory for files to include in the archive. Defaults
|
970
|
+
# to '.' for current directory.
|
366
971
|
# - includes: glob or list of globs for files to select for the archive.
|
972
|
+
# Defaults to '**/*' to include all files recursively.
|
367
973
|
# - excludes: glob or list of globs for files to exclude from the archive.
|
974
|
+
# Defaults to nil to exclude no file.
|
975
|
+
# - dotmatch: tells if joker matches dot files. Optional, defaults to
|
976
|
+
# false.
|
368
977
|
# - dest: the archive file to generate.
|
369
978
|
# - prefix: prefix for archive entries (default to nil).
|
370
979
|
#
|
371
980
|
# Example
|
372
981
|
#
|
373
982
|
# - zip:
|
374
|
-
#
|
375
|
-
#
|
376
|
-
# dest: :zip_archive
|
983
|
+
# excludes: ["build/**/*", "**/*~"]
|
984
|
+
# dest: :zip_archive
|
377
985
|
#
|
378
986
|
# Note
|
379
987
|
#
|
380
988
|
# If archive already exists, files are added to the archive.
|
381
989
|
def zip(parameters)
|
382
990
|
require 'zip/zip'
|
383
|
-
# parse parameters
|
384
991
|
params_desc = {
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
992
|
+
:root => { :mandatory => false, :type => :string },
|
993
|
+
:includes => { :mandatory => true, :type => :string_or_array },
|
994
|
+
:excludes => { :mandatory => false, :type => :string_or_array, :default => nil },
|
995
|
+
:dotmatch => { :mandatory => false, :type => :boolean, :default => false },
|
996
|
+
:dest => { :mandatory => true, :type => :string },
|
997
|
+
:prefix => { :mandatory => false, :type => :string }
|
389
998
|
}
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
prefix
|
397
|
-
|
398
|
-
!prefix or prefix.kind_of?(String)
|
399
|
-
files = select_files(includes, excludes)
|
999
|
+
check_parameters(parameters, params_desc)
|
1000
|
+
root = parameters[:root]
|
1001
|
+
includes = parameters[:includes]
|
1002
|
+
excludes = parameters[:excludes]
|
1003
|
+
dotmatch = parameters[:dotmatch]
|
1004
|
+
dest = parameters[:dest]
|
1005
|
+
prefix = parameters[:prefix]
|
1006
|
+
files = filter_files(includes, excludes, root, dotmatch)
|
400
1007
|
# build the archive
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
1008
|
+
puts "Building ZIP archive '#{dest}'"
|
1009
|
+
begin
|
1010
|
+
zipfile = Zip::ZipFile.open(dest, Zip::ZipFile::CREATE) do |zip|
|
1011
|
+
for file in files
|
1012
|
+
path = (root == nil ? file : File.join(root, file))
|
1013
|
+
entry = prefix ? File.join(prefix, file) : file
|
1014
|
+
puts "Adding '#{entry}'" if @build.listener.verbose
|
1015
|
+
zip.add(entry, path)
|
1016
|
+
end
|
1017
|
+
zip.close
|
1018
|
+
end
|
1019
|
+
rescue
|
1020
|
+
error "Error building ZIP archive: #{$!}"
|
1021
|
+
end
|
1022
|
+
end
|
1023
|
+
|
1024
|
+
# Extract ZIP archive to a destination directory. Existing extracted
|
1025
|
+
# files are not overwritten and result in an error. Parameter is a Hash
|
1026
|
+
# with following entries:
|
1027
|
+
#
|
1028
|
+
# - src: archive to extract.
|
1029
|
+
# - dest: destination directory for extracted files. Optional, defaults
|
1030
|
+
# to current directory.
|
1031
|
+
#
|
1032
|
+
# Example
|
1033
|
+
#
|
1034
|
+
# - unzip:
|
1035
|
+
# src: myarchive.zip
|
1036
|
+
# dest: mydir
|
1037
|
+
def unzip(parameters)
|
1038
|
+
require 'zip/zip'
|
1039
|
+
params_desc = {
|
1040
|
+
:src => { :mandatory => true, :type => :string },
|
1041
|
+
:dest => { :mandatory => false, :type => :string, :default => '.' }
|
1042
|
+
}
|
1043
|
+
check_parameters(parameters, params_desc)
|
1044
|
+
src = parameters[:src]
|
1045
|
+
dest = parameters[:dest]
|
1046
|
+
error "unzip 'src' parameter must be an readable ZIP archive" unless
|
1047
|
+
File.exists?(src) and File.readable?(src)
|
1048
|
+
FileUtils.makedirs(dest) if not File.exists?(dest)
|
1049
|
+
puts "Extracting ZIP file '#{src}' to '#{dest}'"
|
1050
|
+
begin
|
1051
|
+
Zip::ZipFile.foreach(src) do |entry|
|
1052
|
+
puts "Writing '#{entry}'" if @build.listener.verbose
|
1053
|
+
tofile = File.join(dest, entry.name)
|
1054
|
+
if entry.file?
|
1055
|
+
dir = File.dirname(tofile)
|
1056
|
+
FileUtils.makedirs(dir) if not File.exists?(dir)
|
1057
|
+
entry.extract(tofile)
|
1058
|
+
elsif entry.directory?
|
1059
|
+
FileUtils.makedirs(tofile)
|
1060
|
+
end
|
406
1061
|
end
|
407
|
-
|
1062
|
+
rescue
|
1063
|
+
error "Error extracting ZIP archive: #{$!}"
|
408
1064
|
end
|
409
1065
|
end
|
410
1066
|
|
411
1067
|
# Generate a TAR archive. Parameter is a Hash with following entries:
|
412
1068
|
#
|
1069
|
+
# - root: root directory for files to include. Defaults to current
|
1070
|
+
# directory.
|
413
1071
|
# - includes: glob or list of globs for files to select for the archive.
|
1072
|
+
# Defaults to '**/*' to include all files recursively.
|
414
1073
|
# - excludes: glob or list of globs for files to exclude from the archive.
|
1074
|
+
# Defaults to nil to exclude no file.
|
1075
|
+
# - dotmatch: tells if joker matches dot files. Optional, defaults to
|
1076
|
+
# false.
|
415
1077
|
# - dest: the archive file to generate.
|
416
1078
|
#
|
417
1079
|
# Example
|
@@ -423,28 +1085,40 @@ module Bee
|
|
423
1085
|
#
|
424
1086
|
# Note
|
425
1087
|
#
|
426
|
-
# If archive already exists,
|
1088
|
+
# If archive already exists, it's overwritten.
|
427
1089
|
def tar(parameters)
|
428
1090
|
require 'archive/tar/minitar'
|
429
1091
|
# parse parameters
|
430
1092
|
params_desc = {
|
431
|
-
|
432
|
-
|
433
|
-
|
1093
|
+
:root => { :mandatory => false, :type => :string },
|
1094
|
+
:includes => { :mandatory => true, :type => :string_or_array },
|
1095
|
+
:excludes => { :mandatory => false, :type => :string_or_array, :default => nil },
|
1096
|
+
:dotmatch => { :mandatory => false, :type => :boolean, :default => false },
|
1097
|
+
:dest => { :mandatory => true, :type => :string }
|
434
1098
|
}
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
files =
|
1099
|
+
check_parameters(parameters, params_desc)
|
1100
|
+
root = parameters[:root]
|
1101
|
+
includes = parameters[:includes]
|
1102
|
+
excludes = parameters[:excludes]
|
1103
|
+
dotmatch = parameters[:dotmatch]
|
1104
|
+
dest = parameters[:dest]
|
1105
|
+
files = filter_files(includes, excludes, root, dotmatch)
|
442
1106
|
# build the archive
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
1107
|
+
puts "Processing TAR archive '#{dest}'"
|
1108
|
+
begin
|
1109
|
+
current_dir = Dir.pwd
|
1110
|
+
abs_dest = File.expand_path(dest)
|
1111
|
+
Dir.chdir(root) if root
|
1112
|
+
Archive::Tar::Minitar::Output.open(abs_dest) do |tarfile|
|
1113
|
+
for file in files
|
1114
|
+
puts "Adding '#{file}'" if @build.listener.verbose
|
1115
|
+
Archive::Tar::Minitar.pack_file(file, tarfile)
|
1116
|
+
end
|
447
1117
|
end
|
1118
|
+
rescue Exception
|
1119
|
+
error "Error generating TAR archive: #{$!}"
|
1120
|
+
ensure
|
1121
|
+
Dir.chdir(current_dir)
|
448
1122
|
end
|
449
1123
|
end
|
450
1124
|
|
@@ -452,7 +1126,8 @@ module Bee
|
|
452
1126
|
# following entries:
|
453
1127
|
#
|
454
1128
|
# - src: source file to generate GZIP for.
|
455
|
-
# - dest: GZIP file to generate.
|
1129
|
+
# - dest: GZIP file to generate. Defaults to the src file with '.gz'
|
1130
|
+
# extension added.
|
456
1131
|
#
|
457
1132
|
# Example
|
458
1133
|
#
|
@@ -463,61 +1138,173 @@ module Bee
|
|
463
1138
|
require 'zlib'
|
464
1139
|
# parse parameters
|
465
1140
|
params_desc = {
|
466
|
-
|
467
|
-
|
1141
|
+
:src => { :mandatory => true, :type => :string },
|
1142
|
+
:dest => { :mandatory => false, :type => :string }
|
468
1143
|
}
|
469
|
-
|
470
|
-
src
|
471
|
-
dest = parameters[
|
1144
|
+
check_parameters(parameters, params_desc)
|
1145
|
+
src = parameters[:src]
|
1146
|
+
dest = parameters[:dest]
|
1147
|
+
dest = src + '.gz' if not dest
|
472
1148
|
# compress file
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
1149
|
+
puts "Processing GZIP archive '#{dest}'"
|
1150
|
+
begin
|
1151
|
+
File.open(src) do |input|
|
1152
|
+
output = Zlib::GzipWriter.new(File.open(dest, 'wb'))
|
1153
|
+
output.write(input.read)
|
1154
|
+
output.close
|
1155
|
+
end
|
1156
|
+
rescue
|
1157
|
+
error "Error generating GZIP archive: #{$!}"
|
1158
|
+
end
|
1159
|
+
end
|
1160
|
+
|
1161
|
+
# Expand a GZIP archive for a given file. Parameter is a Hash with
|
1162
|
+
# following entries:
|
1163
|
+
#
|
1164
|
+
# - src: GZIP file to expand.
|
1165
|
+
# - dest: destination for expanded file. Destination file can be guessed
|
1166
|
+
# (and thus omitted) for src files '.gz', '.gzip' and '.tgz';
|
1167
|
+
# corresponding dest for latest will be '.tar'.
|
1168
|
+
#
|
1169
|
+
# Example
|
1170
|
+
#
|
1171
|
+
# - gunzip:
|
1172
|
+
# src: "dist.tar.gz"
|
1173
|
+
# dest: "dist.tar"
|
1174
|
+
def gunzip(parameters)
|
1175
|
+
require 'zlib'
|
1176
|
+
# parse parameters
|
1177
|
+
params_desc = {
|
1178
|
+
:src => { :mandatory => true, :type => :string },
|
1179
|
+
:dest => { :mandatory => false, :type => :string }
|
1180
|
+
}
|
1181
|
+
check_parameters(parameters, params_desc)
|
1182
|
+
src = parameters[:src]
|
1183
|
+
dest = parameters[:dest]
|
1184
|
+
error "gunzip 'src' parameter must be an readable GZIP archive" unless
|
1185
|
+
File.exists?(src) and File.readable?(src)
|
1186
|
+
if not dest
|
1187
|
+
if src =~ /.*\.gz$/
|
1188
|
+
dest = src[0..-4]
|
1189
|
+
elsif src =~ /.*\.gzip$/
|
1190
|
+
dest = src[0..-6]
|
1191
|
+
elsif src =~ /.*\.tgz/
|
1192
|
+
dest = src[0..-5]+'.tar'
|
1193
|
+
else
|
1194
|
+
error "gunzip can't guess 'dest' parameter from 'src' file name"
|
1195
|
+
end
|
1196
|
+
end
|
1197
|
+
# expand file
|
1198
|
+
puts "Expanding GZIP archive '#{dest}'"
|
1199
|
+
begin
|
1200
|
+
Zlib::GzipReader.open(src) do |input|
|
1201
|
+
output = File.open(dest, 'wb')
|
1202
|
+
output.write(input.read)
|
1203
|
+
output.close
|
1204
|
+
end
|
1205
|
+
rescue
|
1206
|
+
error "Error expanding GZIP archive: #{$!}"
|
477
1207
|
end
|
478
1208
|
end
|
479
1209
|
|
480
1210
|
# Generate a TAR.GZ archive. Parameter is a Hash with following entries:
|
481
1211
|
#
|
1212
|
+
# - root: root directory for files to include. Defaults to current
|
1213
|
+
# directory.
|
482
1214
|
# - includes: glob or list of globs for files to select for the archive.
|
1215
|
+
# Defaults to '**/*' to include all files recursively.
|
483
1216
|
# - excludes: glob or list of globs for files to exclude from the archive.
|
1217
|
+
# Defaults to nil to exclude no file.
|
1218
|
+
# - dotmatch: tells if joker matches dot files. Optional, defaults to
|
1219
|
+
# false.
|
484
1220
|
# - dest: the archive file to generate.
|
485
1221
|
#
|
486
1222
|
# Example
|
487
1223
|
#
|
488
1224
|
# - targz:
|
489
|
-
#
|
490
|
-
#
|
491
|
-
# dest: :targz_archive
|
1225
|
+
# excludes: ["build/**/*", "**/*~"]
|
1226
|
+
# dest: :targz_archive
|
492
1227
|
#
|
493
1228
|
# Note
|
494
1229
|
#
|
495
|
-
# If archive already exists,
|
1230
|
+
# If archive already exists, it's overwritten.
|
496
1231
|
def targz(parameters)
|
497
1232
|
require 'archive/tar/minitar'
|
498
1233
|
require 'zlib'
|
499
1234
|
# parse parameters
|
500
1235
|
params_desc = {
|
501
|
-
|
502
|
-
|
503
|
-
|
1236
|
+
:root => { :mandatory => false, :type => :string },
|
1237
|
+
:includes => { :mandatory => true, :type => :string_or_array },
|
1238
|
+
:excludes => { :mandatory => false, :type => :string_or_array, :default => nil },
|
1239
|
+
:dotmatch => { :mandatory => false, :type => :boolean, :default => false },
|
1240
|
+
:dest => { :mandatory => true, :type => :string }
|
504
1241
|
}
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
files =
|
1242
|
+
check_parameters(parameters, params_desc)
|
1243
|
+
root = parameters[:root]
|
1244
|
+
includes = parameters[:includes]
|
1245
|
+
excludes = parameters[:excludes]
|
1246
|
+
dotmatch = parameters[:dotmatch]
|
1247
|
+
dest = parameters[:dest]
|
1248
|
+
files = filter_files(includes, excludes, root, dotmatch)
|
512
1249
|
# build the archive
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
1250
|
+
begin
|
1251
|
+
current_dir = Dir.pwd
|
1252
|
+
abs_dest = File.expand_path(dest)
|
1253
|
+
Dir.chdir(root) if root
|
1254
|
+
Archive::Tar::Minitar::Output.
|
1255
|
+
open(Zlib::GzipWriter.new(File.open(abs_dest, 'wb'))) do |tgz|
|
1256
|
+
for file in files
|
1257
|
+
puts "Adding '#{file}'" if @build.listener.verbose
|
1258
|
+
Archive::Tar::Minitar.pack_file(file, tgz)
|
1259
|
+
end
|
517
1260
|
end
|
1261
|
+
rescue
|
1262
|
+
error "Error generating TARGZ archive: #{$!}"
|
1263
|
+
ensure
|
1264
|
+
Dir.chdir(current_dir)
|
518
1265
|
end
|
519
1266
|
end
|
520
1267
|
|
1268
|
+
# Extract TAR archive to a destination directory. Gziped archives are
|
1269
|
+
# managed if their extension is '.tgz' or '.tar.gz'. Extracted files
|
1270
|
+
# are overwritten if they already exist. Parameter is a Hash with
|
1271
|
+
# following entries:
|
1272
|
+
#
|
1273
|
+
# - src: archive to extract.
|
1274
|
+
# - dest: destination directory for extracted files. Optional, defaults
|
1275
|
+
# to current directory.
|
1276
|
+
#
|
1277
|
+
# Example
|
1278
|
+
#
|
1279
|
+
# - untar:
|
1280
|
+
# src: myarchive.tar.gz
|
1281
|
+
# dest: mydir
|
1282
|
+
def untar(parameters)
|
1283
|
+
require 'archive/tar/minitar'
|
1284
|
+
require 'zlib'
|
1285
|
+
params_desc = {
|
1286
|
+
:src => { :mandatory => true, :type => :string },
|
1287
|
+
:dest => { :mandatory => false, :type => :string, :default => '.' }
|
1288
|
+
}
|
1289
|
+
check_parameters(parameters, params_desc)
|
1290
|
+
src = parameters[:src]
|
1291
|
+
dest = parameters[:dest]
|
1292
|
+
error "untar 'src' parameter must be an readable TAR archive" unless
|
1293
|
+
File.exists?(src) and File.readable?(src)
|
1294
|
+
FileUtils.makedirs(dest) if not File.exists?(dest)
|
1295
|
+
puts "Extracting TAR file '#{src}' to '#{dest}'"
|
1296
|
+
begin
|
1297
|
+
if src =~ /\.tar\.gz$/ or src =~ /\.tgz$/
|
1298
|
+
tgz = Zlib::GzipReader.new(File.open(src, 'rb'))
|
1299
|
+
Archive::Tar::Minitar.unpack(tgz, dest)
|
1300
|
+
else
|
1301
|
+
Archive::Tar::Minitar.unpack(src, dest)
|
1302
|
+
end
|
1303
|
+
rescue
|
1304
|
+
error "Error extracting TAR archive: #{$!}"
|
1305
|
+
end
|
1306
|
+
end
|
1307
|
+
|
521
1308
|
end
|
522
1309
|
|
523
1310
|
end
|