bee 0.10.2 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -25,4 +25,4 @@ or go to URL http://www.apache.org/licenses/LICENSE-2.0).
25
25
 
26
26
  = Copyright
27
27
 
28
- bee version 0.10.2 (C) Michel Casabianca & Contributors - 2006-2010
28
+ bee version 0.11.0 (C) Michel Casabianca & Contributors - 2006-2011
@@ -19,6 +19,24 @@ _bee()
19
19
  cur="${COMP_WORDS[COMP_CWORD]}"
20
20
  prev="${COMP_WORDS[COMP_CWORD-1]}"
21
21
 
22
+ case $prev in
23
+ -k)
24
+ tasks="`bee -x`"
25
+ COMPREPLY=( $(compgen -W "${tasks}" -- $cur ) )
26
+ return 0
27
+ ;;
28
+ -t)
29
+ templates="`bee -y`"
30
+ COMPREPLY=( $(compgen -W "${templates}" -- $cur ) )
31
+ return 0
32
+ ;;
33
+ -e)
34
+ templates="`bee -y`"
35
+ COMPREPLY=( $(compgen -W "${templates}" -- $cur ) )
36
+ return 0
37
+ ;;
38
+ esac
39
+
22
40
  if [[ ${cur} == -* ]] ; then
23
41
  opts="`bee -o`"
24
42
  COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
data/bin/bee CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # Copyright 2006-2010 Michel Casabianca <michel.casabianca@gmail.com>
3
+ # Copyright 2006-2011 Michel Casabianca <michel.casabianca@gmail.com>
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -7,7 +7,7 @@ goto endofruby
7
7
  goto endofruby
8
8
  #!/usr/bin/env ruby
9
9
 
10
- # Copyright 2006-2010 Michel Casabianca <michel.casabianca@gmail.com>
10
+ # Copyright 2006-2011 Michel Casabianca <michel.casabianca@gmail.com>
11
11
  #
12
12
  # Licensed under the Apache License, Version 2.0 (the "License");
13
13
  # you may not use this file except in compliance with the License.
@@ -11,11 +11,12 @@
11
11
  years: ""
12
12
  platform: "Gem::Platform::RUBY"
13
13
  summary: ""
14
+ description: ""
14
15
  email: ""
15
16
  homepage: ""
16
17
  rubyforge: ""
17
18
  dependencies:
18
- bee: [">= 0.7.0"]
19
+ bee: [">= 0.11.0"]
19
20
  lib_dir: "lib"
20
21
  test_dir: "test"
21
22
  build_dir: "build"
@@ -9,6 +9,7 @@ SPEC = Gem::Specification.new do |spec|
9
9
  spec.rubyforge_project = '<%= rubyforge %>'
10
10
  spec.platform = <%= platform %>
11
11
  spec.summary = '<%= summary %>'
12
+ spec.description = '<%= description %>'
12
13
  spec.files = Dir.glob('{bin,lib}/**/*').delete_if do |file|
13
14
  file =~ /CVS/
14
15
  end
@@ -1,4 +1,4 @@
1
- require 'bee_task'
1
+ require 'bee_task_package'
2
2
 
3
3
  module Bee
4
4
 
@@ -12,6 +12,7 @@
12
12
  years: ""
13
13
  platform: "Gem::Platform::RUBY"
14
14
  summary: ""
15
+ description: ""
15
16
  email: ""
16
17
  homepage: "http://<%= project_name %>.rubyforge.org"
17
18
  rubyforge: ""
@@ -9,6 +9,7 @@ SPEC = Gem::Specification.new do |spec|
9
9
  spec.rubyforge_project = '<%= rubyforge %>'
10
10
  spec.platform = <%= platform %>
11
11
  spec.summary = '<%= summary %>'
12
+ spec.description = '<%= description %>'
12
13
  spec.files = Dir.glob('{lib,test,egg}/**/*').delete_if do |file|
13
14
  file =~ /CVS/
14
15
  end
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'bee'
3
+ require 'bee_build'
4
4
  require 'test/unit'
5
5
  $:.unshift(File.join(File.expand_path(File.dirname(__FILE__))))
6
6
  require 'test_build'
@@ -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.
@@ -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,30 +12,29 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # Test build listener.
15
+ require 'rubygems'
16
+
16
17
  class TestBuildListener
17
18
 
19
+ attr_reader :formatter
18
20
  attr_reader :started
19
21
  attr_reader :finished
20
22
  attr_reader :targets
21
23
  attr_reader :tasks
22
24
  attr_reader :success
23
25
  attr_reader :errors
24
- attr_accessor :output
25
- attr_reader :verbose
26
+ attr_accessor :throw_error
27
+ attr_accessor :prompt
26
28
 
27
- def initialize
28
- @targets = []
29
- @tasks = []
30
- @output = ''
31
- @verbose = false
29
+ def initialize()
30
+ reset
32
31
  end
33
-
34
- def build_started(build)
32
+
33
+ def build_started(build, dry=false)
35
34
  @started = true
36
35
  end
37
36
 
38
- def build_finished(build)
37
+ def build_finished()
39
38
  @finished = true
40
39
  end
41
40
 
@@ -44,11 +43,56 @@ class TestBuildListener
44
43
  end
45
44
 
46
45
  def task(task)
47
- @tasks << tasks
46
+ @tasks << task
48
47
  end
49
48
 
50
49
  def error(exception)
51
- @errors = exception
50
+ if throw_error
51
+ raise exception
52
+ else
53
+ @errors << exception
54
+ end
55
+ end
56
+
57
+ def recover
58
+ @success = true
59
+ end
60
+
61
+ def reset
62
+ @formatter = TestBuildFormatter.new(self)
63
+ @started = false
64
+ @finished = false
65
+ @targets = []
66
+ @tasks = []
67
+ @success = false
68
+ @errors = []
69
+ @throw_error = false
70
+ @prompt = ''
71
+ end
72
+
73
+ def output()
74
+ return @formatter.output
75
+ end
76
+
77
+ def clear()
78
+ @formatter.clear()
79
+ end
80
+
81
+ def error?
82
+ return @errors.length > 0
83
+ end
84
+
85
+ end
86
+
87
+ class TestBuildFormatter
88
+
89
+ attr_reader :verbose
90
+ attr_reader :output
91
+
92
+ def initialize(listener)
93
+ @listener = listener
94
+ @verbose = false
95
+ @output = ''
52
96
  end
53
97
 
54
98
  def print(text)
@@ -59,4 +103,8 @@ class TestBuildListener
59
103
  @output << text + "\n"
60
104
  end
61
105
 
106
+ def clear()
107
+ @output = ''
108
+ end
109
+
62
110
  end
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # Copyright 2006-2010 Michel Casabianca <michel.casabianca@gmail.com>
3
+ # Copyright 2006-2011 Michel Casabianca <michel.casabianca@gmail.com>
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -6,7 +6,7 @@
6
6
  # Build properties
7
7
  - properties:
8
8
  name: "<%= name %>"
9
- version: "0.0.0"
9
+ version: "0.0.1"
10
10
  build: "build"
11
11
  clean_dirs: [:build]
12
12
  clean_files: ["**/*~", "**/.#*", "**/.DS_Store"]
@@ -4,7 +4,7 @@
4
4
 
5
5
  - properties:
6
6
  name: "<%= name %>"
7
- version: "0.0.0"
7
+ version: "0.0.1"
8
8
  build: "build"
9
9
  zip_prefix: "#{name}-#{version}"
10
10
  zip_file: "#{build}/#{zip_prefix}.zip"
@@ -6,7 +6,7 @@
6
6
  # Build properties
7
7
  - properties:
8
8
  name: <%= project_name %>
9
- version: "0.0.0"
9
+ version: "0.0.1"
10
10
  build: "build"
11
11
  zip: "#{build}/#{name}-#{version}.zip"
12
12
  clean_dirs: [:build]
@@ -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.
@@ -14,17 +14,16 @@
14
14
 
15
15
  require 'rubygems'
16
16
  require 'yaml'
17
- require 'bee_task'
18
- require 'bee_target'
19
17
  require 'bee_util'
20
18
  require 'bee_context'
21
19
  require 'bee_properties'
20
+ require 'bee_target'
21
+ require 'bee_targets'
22
+ require 'bee_task_packagemanager'
22
23
 
23
- # Module for Bee core classes.
24
24
  module Bee
25
25
 
26
- # Class for a build. This class is built from an object resulting from YAML
27
- # build file parsing.
26
+ # Class for a build, built from an object resulting from YAML build file parsing.
28
27
  class Build
29
28
 
30
29
  include Bee::Util::BuildErrorMixin
@@ -54,8 +53,6 @@ module Bee
54
53
  attr_reader :extends
55
54
  # Abstractness.
56
55
  attr_reader :abstract
57
- # Default target, specified with default entry or fist target in build file.
58
- attr_accessor :default
59
56
  # Build description.
60
57
  attr_reader :description
61
58
  # Build properties.
@@ -86,15 +83,10 @@ module Bee
86
83
  end
87
84
  begin
88
85
  yaml = Bee::Util::get_file(file)
89
- rescue
90
- raise Bee::Util::BuildError.
91
- new("Error loading build file '#{file}': #{$!}")
92
- end
93
- begin
94
86
  object = YAML::load(yaml)
95
87
  rescue
96
88
  raise Bee::Util::BuildError.
97
- new("YAML syntax error in build file '#{file}': #{$!}")
89
+ new("Error loading build file '#{file}': #{$!}")
98
90
  end
99
91
  return Build.new(object, file, properties)
100
92
  end
@@ -108,42 +100,37 @@ module Bee
108
100
  @file = file
109
101
  @base = get_base(@file)
110
102
  @here = here
111
- @properties = Properties.new(self)
112
- @context = Context.new(@properties)
113
- @properties.evaluate(@context)
103
+ @properties = Bee::Properties.new
104
+ @scripts = []
114
105
  @targets = Targets.new(self)
115
106
  parse(object)
116
107
  @properties.overwrite(properties)
108
+ @properties.defaults({:base => @base, :here => @here})
109
+ @context = Context.new(@properties.expressions, @scripts)
117
110
  @package_manager = Bee::Task::PackageManager.new(self)
118
111
  end
119
112
 
120
- # Evaluate properties.
121
- def evaluate_properties
122
- @properties.evaluate(@context)
123
- end
124
-
125
- # Run build:
113
+ # Run build. Raise a BuildError exception on build error if no listener
114
+ # was given to be notified of the build failure:
126
115
  # - targets: list of targets to run.
127
116
  # - listener: listener for the build.
128
117
  def run(targets, listener=nil, dry=false)
129
118
  @listener = listener
130
119
  working_directory = Dir.getwd
131
- @listener.build_started(self, dry) if @listener
120
+ @listener.start(self, dry) if @listener
132
121
  begin
133
122
  error "Abstract build file, must be extended to run" if @abstract
134
- evaluate_properties
135
123
  if not Bee::Util::url?(@base)
136
124
  Dir.chdir(@base)
137
125
  end
126
+ @context.evaluate
138
127
  @targets.run(targets, dry)
139
- @listener.build_finished(self, dry) if @listener
140
- rescue Bee::Util::BuildError => e
141
- if @listener
142
- @listener.error(e)
143
- else
144
- raise e
145
- end
128
+ @listener.success() if @listener
129
+ rescue Bee::Util::BuildError
130
+ @listener.error($!) if @listener
131
+ raise $!
146
132
  ensure
133
+ @listener.stop() if @listener
147
134
  Dir.chdir(working_directory)
148
135
  remove_instance_variable(:@listener)
149
136
  end
@@ -159,11 +146,22 @@ module Bee
159
146
  for entry in object
160
147
  if entry.key?(Build::KEY)
161
148
  parse_build(entry)
162
- error "Build info entry must be first one in build file" if
163
- not first
149
+ error "Build info entry must be first one in build file" if not first
164
150
  first = false
165
151
  elsif entry.key?(Properties::KEY)
166
- @properties.write(entry)
152
+ properties = entry[Properties::KEY]
153
+ # if properties is a string, this is a YAML file to load as a Hash
154
+ if properties.kind_of?(String)
155
+ filename = properties
156
+ begin
157
+ properties = YAML::load(Bee::Util::get_file(filename, @base))
158
+ @properties.write(properties)
159
+ rescue Exception
160
+ error "Error loading properties file '#{filename}': #{$!}"
161
+ end
162
+ else
163
+ @properties.write(properties)
164
+ end
167
165
  first = false
168
166
  elsif entry.key?(Target::KEY)
169
167
  @targets.add(entry)
@@ -175,7 +173,7 @@ module Bee
175
173
  # manage extended builds
176
174
  if @extends
177
175
  for parent in @extends
178
- @properties.extend(parent.properties)
176
+ @properties.extend(parent.properties.expressions)
179
177
  @targets.extend(parent.targets)
180
178
  end
181
179
  end
@@ -191,10 +189,12 @@ module Bee
191
189
  end
192
190
  error "Duplicate build info" if @name
193
191
  @name = entry['build']
194
- @default = entry['default']
195
- @targets.default = @default
192
+ @targets.default = entry['default']
196
193
  @description = entry['description']
197
194
  @abstract = entry['abstract']
195
+ # check that 'default' entry is a string
196
+ error "'default' entry of the 'build' block must be a string" if
197
+ @targets.default and !@targets.default.kind_of?(String)
198
198
  # load parents build if any
199
199
  parents = Array(entry['extends'])
200
200
  if parents.length > 0
@@ -217,7 +217,7 @@ module Bee
217
217
  collisions += properties & parent_properties
218
218
  properties += parent_properties
219
219
  end
220
- collisions = collisions - Properties::SYSTEM_PROPERTIES
220
+ collisions = collisions - Bee::Properties::SYSTEM_PROPERTIES
221
221
  collisions = collisions.uniq.map { |e| e.to_s }.sort
222
222
  if collisions.length > 0
223
223
  error "Properties in parents are colliding: #{collisions.join(', ')}"
@@ -236,18 +236,7 @@ module Bee
236
236
  end
237
237
  # load context files if any
238
238
  context = entry['context']
239
- if context
240
- context = Array(context)
241
- for script in context
242
- begin
243
- evaluated = @context.evaluate_object(script)
244
- source = Bee::Util::get_file(evaluated, @base)
245
- @context.evaluate_script(source)
246
- rescue Exception
247
- error "Error loading context '#{script}': #{$!}"
248
- end
249
- end
250
- end
239
+ @scripts = Array(context) if context
251
240
  end
252
241
 
253
242
  # Get base for a given file.
@@ -257,7 +246,7 @@ module Bee
257
246
  if Bee::Util::url?(file)
258
247
  return File.dirname(file)
259
248
  else
260
- return File.expand_path(File.dirname(Bee::Util::absolute_path(file, Dir.pwd)))
249
+ return File.expand_path(File.dirname(file))
261
250
  end
262
251
  else
263
252
  return File.expand_path(Dir.pwd)
@@ -266,134 +255,6 @@ module Bee
266
255
 
267
256
  end
268
257
 
269
- # Class to manage targets in a build.
270
- class Targets
271
-
272
- include Bee::Util::BuildErrorMixin
273
-
274
- # Parent build.
275
- attr_reader :build
276
- # Targets hash by name.
277
- attr_reader :hash
278
- # Targets already run.
279
- attr_reader :already_run
280
- # Default target.
281
- attr_accessor :default
282
-
283
- # Constructor.
284
- # - build: build object.
285
- def initialize(build)
286
- @build = build
287
- @hash = {}
288
- @already_run = []
289
- end
290
-
291
- # Add a new target.
292
- # - object: object tree resulting from YAML build file parsing.
293
- def add(object)
294
- begin
295
- target = Target.new(object, self)
296
- rescue
297
- error "Error parsing target '#{object[Target::KEY]}': #{$!}"
298
- end
299
- error "Duplicate target definition: '#{target.name}'" if
300
- @hash.has_key?(target.name)
301
- @hash[target.name] = [target]
302
- if !@default
303
- @default = target.name
304
- @build.default = target.name
305
- end
306
- end
307
-
308
- # Extend parent targets.
309
- # - parent: parent targets.
310
- def extend(parent)
311
- # set appropriate targets for targets of parent
312
- for targets in parent.hash.values
313
- for target in targets
314
- target.targets = self
315
- end
316
- end
317
- # insert parent targets before current ones
318
- for name in parent.hash.keys
319
- if @hash[name]
320
- @hash[name] = parent.hash[name] + @hash[name]
321
- # clean dependencies for redefined targets
322
- for target in parent.hash[name]
323
- target.depends.clear
324
- end
325
- # copy documentation of parent if target not documented
326
- if not @hash[name].last.description
327
- description = nil
328
- for target in parent.hash[name]
329
- description = target.description || description
330
- end
331
- @hash[name].last.description = description
332
- end
333
- else
334
- @hash[name] = parent.hash[name]
335
- end
336
- end
337
- # set default default target to parent one if none was set
338
- @default = @default || parent.default
339
- end
340
-
341
- # Run targets.
342
- # - targets: list of target names to run.
343
- def run(targets, dry)
344
- error "No default target given" if (!@default and targets.length == 0)
345
- targets = [@default] if targets.length == 0
346
- for target in targets
347
- run_target(target, dry)
348
- @already_run.clear
349
- end
350
- end
351
-
352
- # Call super target.
353
- # - target: target that calls super.
354
- def call_super(target, dry=false)
355
- index = @hash[target.name].index(target)
356
- error "No super target to call for '#{target.name}'" if index == 0
357
- index -= 1
358
- @hash[target.name][index].run(dry)
359
- end
360
-
361
- # Tells if a given target is last in hierarchy.
362
- # - target: given target.
363
- def is_last(target)
364
- index = @hash[target.name].index(target)
365
- last = @hash[target.name].size - 1
366
- return index == last
367
- end
368
-
369
- # Run a given target.
370
- # - target: the target to run.
371
- def run_target(target, dry=false)
372
- error "Target '#{target}' not found" if not @hash[target]
373
- if not @already_run.include?(target)
374
- @already_run << target
375
- @hash[target].last.run(dry)
376
- end
377
- end
378
-
379
- # Return targets description as a hash of descriptions indexed by
380
- # target name. Dependencies are added after target description.
381
- def description
382
- description = {}
383
- for name in @hash.keys
384
- text = @hash[name].last.description
385
- if @hash[name].last.depends and @hash[name].last.depends.length > 0
386
- depends = ' [' + @hash[name].last.depends.join(', ') + ']'
387
- else
388
- depends = nil
389
- end
390
- description[name] = (text ? text : '') + (depends ? depends : '')
391
- end
392
- return description
393
- end
394
-
395
- end
396
-
397
258
  # Return Bee version. Try to load bee_version file or return UNKNOWN.
398
259
  def version
399
260
  begin