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 +1 -1
- data/bin/bash_completion_bee +18 -0
- data/bin/bee +1 -1
- data/bin/bee.bat +1 -1
- data/egg/application/build.yml +2 -1
- data/egg/application/gem.spec.erb +1 -0
- data/egg/package/bee_task.erb +1 -1
- data/egg/package/build.erb +1 -0
- data/egg/package/gem_spec.erb +1 -0
- data/egg/package/test.erb +1 -1
- data/egg/package/test_build.rb +1 -1
- data/egg/package/test_build_listener.rb +62 -14
- data/egg/package/test_suite.rb +1 -1
- data/egg/script/build.yml +1 -1
- data/egg/sinatra/build.yml +1 -1
- data/egg/xmlrpc/build.yml +1 -1
- data/lib/{bee.rb → bee_build.rb} +41 -180
- data/lib/bee_console.rb +45 -466
- data/lib/bee_console_formatter.rb +314 -0
- data/lib/bee_console_style.rb +222 -0
- data/lib/bee_context.rb +108 -45
- data/lib/bee_listener.rb +114 -0
- data/lib/bee_properties.rb +47 -76
- data/lib/bee_target.rb +36 -19
- data/lib/bee_targets.rb +147 -0
- data/lib/bee_task_default.rb +78 -60
- data/lib/{bee_task.rb → bee_task_package.rb} +16 -87
- data/lib/bee_task_packagemanager.rb +135 -0
- data/lib/bee_util.rb +58 -56
- data/lib/bee_version.rb +1 -1
- metadata +56 -22
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2006-
|
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,12 +13,11 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
require 'rubygems'
|
16
|
-
require '
|
16
|
+
require 'bee_build'
|
17
17
|
require 'bee_util'
|
18
18
|
|
19
19
|
module Bee
|
20
20
|
|
21
|
-
# Module for bee tasks.
|
22
21
|
module Task
|
23
22
|
|
24
23
|
# Base class for task package. Provides methods to print output using
|
@@ -28,11 +27,19 @@ module Bee
|
|
28
27
|
class Package < Bee::Util::MethodInfoBase
|
29
28
|
|
30
29
|
include Bee::Util::BuildErrorMixin
|
30
|
+
|
31
|
+
# Verbosity indicator
|
32
|
+
attr_reader :verbose
|
31
33
|
|
32
34
|
# Constructor.
|
33
35
|
# - build: the build we are running.
|
34
36
|
def initialize(build)
|
35
37
|
@build = build
|
38
|
+
if @build and @build.listener
|
39
|
+
@verbose = @build.listener.formatter.verbose
|
40
|
+
else
|
41
|
+
@verbose = false
|
42
|
+
end
|
36
43
|
end
|
37
44
|
|
38
45
|
protected
|
@@ -50,7 +57,7 @@ module Bee
|
|
50
57
|
for param in description.keys
|
51
58
|
error "#{task} '#{param}' parameter is mandatory" unless
|
52
59
|
params[param.to_s] or description[param][:mandatory] == false
|
53
|
-
if params[param.to_s]
|
60
|
+
if params[param.to_s] != nil
|
54
61
|
case description[param][:type]
|
55
62
|
when :string
|
56
63
|
error "#{task} '#{param}' parameter must be a string" unless
|
@@ -66,7 +73,7 @@ module Bee
|
|
66
73
|
params[param.to_s].kind_of?(Numeric)
|
67
74
|
when :boolean
|
68
75
|
error "#{task} '#{param}' parameter must be a boolean" unless
|
69
|
-
params[param.to_s] == true or params[param] == false
|
76
|
+
params[param.to_s] == true or params[param.to_s] == false
|
70
77
|
when :array
|
71
78
|
error "#{task} '#{param}' parameter must be an array" unless
|
72
79
|
params[param.to_s].kind_of?(Array)
|
@@ -152,8 +159,8 @@ module Bee
|
|
152
159
|
# Print text on the console.
|
153
160
|
# - text: text to print.
|
154
161
|
def print(text)
|
155
|
-
if @build.listener
|
156
|
-
@build.listener.print(text)
|
162
|
+
if @build and @build.listener
|
163
|
+
@build.listener.formatter.print(text)
|
157
164
|
else
|
158
165
|
Kernel.print(text)
|
159
166
|
end
|
@@ -162,93 +169,15 @@ module Bee
|
|
162
169
|
# Puts text on the console.
|
163
170
|
# - text: text to puts.
|
164
171
|
def puts(text)
|
165
|
-
if @build.listener
|
166
|
-
@build.listener.puts(text)
|
172
|
+
if @build and @build.listener
|
173
|
+
@build.listener.formatter.puts(text)
|
167
174
|
else
|
168
175
|
Kernel.puts(text)
|
169
176
|
end
|
170
177
|
end
|
171
178
|
|
172
|
-
# Prompts the user for a string.
|
173
|
-
# Return the user input string.
|
174
|
-
def gets
|
175
|
-
if @build.listener
|
176
|
-
return @build.listener.gets
|
177
|
-
else
|
178
|
-
return Kernel::STDIN.gets
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
179
|
end
|
183
180
|
|
184
|
-
# Package manager is responsible for loading packages and calling tasks.
|
185
|
-
class PackageManager
|
186
|
-
|
187
|
-
include Bee::Util::BuildErrorMixin
|
188
|
-
|
189
|
-
# Constructor.
|
190
|
-
# - build: the build we are running.
|
191
|
-
def initialize(build)
|
192
|
-
@build = build
|
193
|
-
@packages = {}
|
194
|
-
end
|
195
|
-
|
196
|
-
# Run a given task.
|
197
|
-
# - task: YAML object for the task to run.
|
198
|
-
def run_task(task)
|
199
|
-
packaged = task.keys[0]
|
200
|
-
package, name = Bee::Util::get_package_name(packaged)
|
201
|
-
parameters = @build.context.evaluate_object(task[packaged])
|
202
|
-
if not @packages[package]
|
203
|
-
load_package(package)
|
204
|
-
end
|
205
|
-
error "Task '#{name}' not found in package '#{package}'" if
|
206
|
-
not @packages[package].respond_to?(name)
|
207
|
-
@packages[package].send(name, parameters)
|
208
|
-
end
|
209
|
-
|
210
|
-
# Get help for a given task.
|
211
|
-
# - task: YAML object for the task to run.
|
212
|
-
def help_task(task)
|
213
|
-
package, name = Bee::Util::get_package_name(task)
|
214
|
-
if not @packages[package]
|
215
|
-
load_package(package)
|
216
|
-
end
|
217
|
-
help = {}
|
218
|
-
if name == '?'
|
219
|
-
methods = @packages[package].class.public_instance_methods(false)
|
220
|
-
for method in methods
|
221
|
-
help[method] = @packages[package].class.method_info(method).comment
|
222
|
-
end
|
223
|
-
return help
|
224
|
-
else
|
225
|
-
error "Task '#{name}' not found in package '#{package}'" if
|
226
|
-
not @packages[package].respond_to?(name)
|
227
|
-
help[task] = @packages[package].class.method_info(name).comment
|
228
|
-
end
|
229
|
-
return help
|
230
|
-
end
|
231
|
-
|
232
|
-
private
|
233
|
-
|
234
|
-
# Load a given package using introspection: we try to instantiate class
|
235
|
-
# named after the package capitalized, in module Bee::Task.
|
236
|
-
# - package: the package name.
|
237
|
-
def load_package(package)
|
238
|
-
package = 'default' if not package
|
239
|
-
package.downcase!
|
240
|
-
script = "bee_task_#{package}"
|
241
|
-
clazz = package.capitalize
|
242
|
-
begin
|
243
|
-
require script
|
244
|
-
@packages[package] = Bee::Task.const_get(clazz).new(@build)
|
245
|
-
rescue Exception
|
246
|
-
error "Task package '#{package}' not found"
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
end
|
251
|
-
|
252
181
|
end
|
253
182
|
|
254
183
|
end
|
@@ -0,0 +1,135 @@
|
|
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
|
+
|
18
|
+
module Bee
|
19
|
+
|
20
|
+
module Task
|
21
|
+
|
22
|
+
# Package manager is responsible for loading packages and calling tasks.
|
23
|
+
class PackageManager
|
24
|
+
|
25
|
+
include Bee::Util::BuildErrorMixin
|
26
|
+
|
27
|
+
# Constructor.
|
28
|
+
# - build: the build we are running.
|
29
|
+
def initialize(build)
|
30
|
+
@build = build
|
31
|
+
@packages = {}
|
32
|
+
end
|
33
|
+
|
34
|
+
# Run a given task.
|
35
|
+
# - task: YAML object for the task to run.
|
36
|
+
def run_task(task)
|
37
|
+
packaged = task.keys[0]
|
38
|
+
package, name = Bee::Util::get_package_name(packaged)
|
39
|
+
parameters = @build.context.evaluate_object(task[packaged])
|
40
|
+
if not @packages[package]
|
41
|
+
@packages[package] = Bee::Task::PackageManager.load_package(package, @build)
|
42
|
+
end
|
43
|
+
error "Task '#{name}' not found in package '#{package}'" if
|
44
|
+
not @packages[package].respond_to?(name)
|
45
|
+
@packages[package].send(name, parameters)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Get help for a given task.
|
49
|
+
# - task: YAML object for the task to run.
|
50
|
+
def help_task(task)
|
51
|
+
package, name = Bee::Util::get_package_name(task)
|
52
|
+
if not @packages[package]
|
53
|
+
@packages[package] = Bee::Task::PackageManager.load_package(package, @build)
|
54
|
+
end
|
55
|
+
help = {}
|
56
|
+
if name == '?'
|
57
|
+
methods = @packages[package].class.public_instance_methods(false)
|
58
|
+
for method in methods
|
59
|
+
help[method] = @packages[package].class.method_info(method).comment
|
60
|
+
end
|
61
|
+
return help
|
62
|
+
else
|
63
|
+
error "Task '#{name}' not found in package '#{package}'" if
|
64
|
+
not @packages[package].respond_to?(name)
|
65
|
+
help[task] = @packages[package].class.method_info(name).comment
|
66
|
+
end
|
67
|
+
return help
|
68
|
+
end
|
69
|
+
|
70
|
+
# List all available tasks.
|
71
|
+
def self.list_tasks
|
72
|
+
names = [nil] + self.find_gems(/^bee_/).map {|gem| gem.name[4..-1]}
|
73
|
+
tasks = []
|
74
|
+
for name in names
|
75
|
+
package = self.load_package(name)
|
76
|
+
methods = package.class.public_instance_methods(false)
|
77
|
+
if name
|
78
|
+
methods.map! {|method| "#{name}.#{method}"}
|
79
|
+
end
|
80
|
+
tasks += methods
|
81
|
+
end
|
82
|
+
return tasks.sort
|
83
|
+
end
|
84
|
+
|
85
|
+
# List all available templates.
|
86
|
+
def self.list_templates
|
87
|
+
gems = self.find_gems(/^bee$/, /^bee_/)
|
88
|
+
templates = []
|
89
|
+
for gem in gems
|
90
|
+
package = gem.name == 'bee' ? nil : gem.name[4..-1]
|
91
|
+
for file in gem.files
|
92
|
+
if file =~ /egg\/(\w+?).yml/
|
93
|
+
if package
|
94
|
+
templates << "#{package}.#{$1}"
|
95
|
+
else
|
96
|
+
templates << $1
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
return templates.sort
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
# Load a given package using introspection: we try to instantiate class
|
107
|
+
# named after the package capitalized, in module Bee::Task.
|
108
|
+
# - package: the package name.
|
109
|
+
def self.load_package(package, build=nil)
|
110
|
+
package = 'default' if not package
|
111
|
+
package.downcase!
|
112
|
+
script = "bee_task_#{package}"
|
113
|
+
clazz = package.capitalize
|
114
|
+
begin
|
115
|
+
require script
|
116
|
+
return Bee::Task.const_get(clazz).new(build)
|
117
|
+
rescue Exception
|
118
|
+
raise Bee::Util::BuildError.new("Task package '#{package}' not found")
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.find_gems(*patterns)
|
123
|
+
gems = []
|
124
|
+
index = Gem::SourceIndex.from_installed_gems()
|
125
|
+
for pattern in patterns
|
126
|
+
gems += index.find_name(pattern)
|
127
|
+
end
|
128
|
+
return gems
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
data/lib/bee_util.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2006-
|
1
|
+
# Copyright 2006-2011 Michel Casabianca <michel.casabianca@gmail.com>
|
2
2
|
# 2006 Avi Bryant
|
3
3
|
#
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -22,13 +22,11 @@ module Bee
|
|
22
22
|
|
23
23
|
# Limit of number of HTTP redirections to follow.
|
24
24
|
HTTP_REDIRECTIONS_LIMIT = 10
|
25
|
-
# README file where copyright is extracted.
|
26
|
-
README_FILE = 'README'
|
27
25
|
# Default package name.
|
28
26
|
DEFAULT_PACKAGE = 'default'
|
29
|
-
# Compact pattern for resource
|
27
|
+
# Compact pattern for resource (':gem.file[version]')
|
30
28
|
COMPACT_PATTERN = /^:(.*?)\.(.*?)(\[(.*)\])?$/
|
31
|
-
# Expanded pattern for resource
|
29
|
+
# Expanded pattern for resource ('ruby://gem:version/file')
|
32
30
|
EXPANDED_PATTERN = /^ruby:\/\/(.*?)(:(.*?))?\/(.*)$/
|
33
31
|
# Default terminal width
|
34
32
|
DEFAULT_TERM_WIDTH = (RUBY_PLATFORM =~ /win32/ ? 79 : 80)
|
@@ -50,18 +48,11 @@ module Bee
|
|
50
48
|
end
|
51
49
|
end
|
52
50
|
|
53
|
-
#
|
54
|
-
|
55
|
-
|
56
|
-
readme = File.join(File.dirname(__FILE__), '..', README_FILE)
|
57
|
-
begin
|
58
|
-
copyright = File.read(readme).strip!.split("\n")[-1]
|
59
|
-
rescue
|
60
|
-
copyright = nil
|
61
|
-
end
|
62
|
-
return copyright
|
51
|
+
# Tells if we are running under Windows.
|
52
|
+
def self.windows?
|
53
|
+
return RUBY_PLATFORM =~ /(mswin|ming)/
|
63
54
|
end
|
64
|
-
|
55
|
+
|
65
56
|
# Parse packaged name and return package and name.
|
66
57
|
# - packaged: packaged name (such as 'foo.bar').
|
67
58
|
# Return: package ('foo') and name ('bar').
|
@@ -76,7 +67,7 @@ module Bee
|
|
76
67
|
|
77
68
|
# Get a given file or URL. Manages HTTP redirections.
|
78
69
|
# - location: file path, resource or URL of the file to get.
|
79
|
-
# - base: base for relative files (defaults to nil).
|
70
|
+
# - base: base for relative files (defaults to nil, which is current dir).
|
80
71
|
def self.get_file(location, base=nil)
|
81
72
|
base = base || Dir.pwd
|
82
73
|
abs = absolute_path(location, base)
|
@@ -101,68 +92,70 @@ module Bee
|
|
101
92
|
find(file)
|
102
93
|
end
|
103
94
|
|
104
|
-
#
|
105
|
-
# -
|
106
|
-
def self.url?(
|
107
|
-
return
|
95
|
+
# Tells is a given location is a URL (starting with 'http://').
|
96
|
+
# - location: location to consider as a string.
|
97
|
+
def self.url?(location)
|
98
|
+
return false if not location.kind_of?(String)
|
99
|
+
return location =~ /^http:\/\//
|
100
|
+
end
|
101
|
+
|
102
|
+
# Tells is a given location is a resource (starting with 'ruby://' or ':').
|
103
|
+
# - location: location to consider as a string.
|
104
|
+
def self.resource?(location)
|
105
|
+
return false if not location.kind_of?(String)
|
106
|
+
return location =~ /^ruby:\/\// || location =~ /^:/
|
108
107
|
end
|
109
108
|
|
110
109
|
# Tells if a given path is absolute.
|
111
|
-
# -
|
112
|
-
def self.absolute_path?(
|
113
|
-
if url?(
|
110
|
+
# - path: path to consider.
|
111
|
+
def self.absolute_path?(path)
|
112
|
+
if url?(path) or resource?(path)
|
114
113
|
return true
|
115
114
|
else
|
116
|
-
|
117
|
-
|
118
|
-
return location =~ /^(([a-z]|[A-Z]):)?\//
|
115
|
+
if windows?
|
116
|
+
return path =~ /^(([a-zA-Z]):)?\//
|
119
117
|
else
|
120
|
-
return
|
118
|
+
return path =~ /^\//
|
121
119
|
end
|
122
120
|
end
|
123
121
|
end
|
124
122
|
|
125
|
-
#
|
126
|
-
# to
|
127
|
-
# -
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
location = resource_path(location)
|
123
|
+
# Return absolute path for a given path and optional base:
|
124
|
+
# - path: relative path to get absolute path for.
|
125
|
+
# - base: optional base for path (defaults to current directory).
|
126
|
+
def self.absolute_path(path, base=nil)
|
127
|
+
if absolute_path?(path)
|
128
|
+
if resource?(path)
|
129
|
+
path = resource_path(path)
|
133
130
|
end
|
134
|
-
return
|
131
|
+
return path
|
135
132
|
else
|
136
|
-
|
133
|
+
base = Dir.pwd if not base
|
134
|
+
return File.join(base, path)
|
137
135
|
end
|
138
136
|
end
|
139
137
|
|
140
138
|
# Get a given URL.
|
141
139
|
# - url: URL to get.
|
142
140
|
# - limit: redirectrion limit (defaults to HTTP_REDIRECTIONS_LIMIT).
|
143
|
-
def self.fetch(url, limit
|
141
|
+
def self.fetch(url, limit=HTTP_REDIRECTIONS_LIMIT)
|
144
142
|
raise 'HTTP redirect too deep' if limit == 0
|
145
143
|
response = Net::HTTP.get_response(URI.parse(url))
|
146
144
|
case response
|
147
145
|
when Net::HTTPSuccess
|
148
146
|
response.body
|
149
147
|
when Net::HTTPRedirection
|
150
|
-
fetch(response['location'], limit
|
148
|
+
fetch(response['location'], limit-1)
|
151
149
|
else
|
152
150
|
response.error!
|
153
151
|
end
|
154
152
|
end
|
155
153
|
|
156
|
-
#
|
157
|
-
# -
|
158
|
-
|
159
|
-
return location.to_s =~ /^ruby:\/\// || location.to_s =~ /^:/
|
160
|
-
end
|
161
|
-
|
162
|
-
# Return the path to a given resoure and test that file exists.
|
163
|
-
# - resource: the resource (expanded or compact pattern).
|
154
|
+
# Return absolute path to a given resoure:
|
155
|
+
# - resource: the resource (expanded patterns are like ':gem.file[version]'
|
156
|
+
# and compact ones like 'ruby://gem:version/file').
|
164
157
|
def self.resource_path(resource)
|
165
|
-
# get gem, version and path from resource
|
158
|
+
# get gem, version and path from resource or interrupt build with an error
|
166
159
|
case resource
|
167
160
|
when COMPACT_PATTERN
|
168
161
|
gem, version, path = $1, $4, $2
|
@@ -178,8 +171,7 @@ module Bee
|
|
178
171
|
not gem_descriptor
|
179
172
|
else
|
180
173
|
gem_descriptor = Gem.source_index.find_name(gem)[0]
|
181
|
-
raise "Gem '#{gem}' was not found" if
|
182
|
-
not gem_descriptor
|
174
|
+
raise "Gem '#{gem}' was not found" if not gem_descriptor
|
183
175
|
end
|
184
176
|
# get resource path
|
185
177
|
gem_path = gem_descriptor.full_gem_path
|
@@ -188,7 +180,7 @@ module Bee
|
|
188
180
|
end
|
189
181
|
|
190
182
|
# Find a given template and return associated file.
|
191
|
-
# - template: template to look for.
|
183
|
+
# - template: template to look for (like 'foo.bar').
|
192
184
|
# return: found associated file.
|
193
185
|
def self.find_template(template)
|
194
186
|
raise Bee::Util::BuildError.
|
@@ -212,7 +204,7 @@ module Bee
|
|
212
204
|
end
|
213
205
|
|
214
206
|
# Search files for a given templates that might contain a joker (*).
|
215
|
-
# - template: template to look for.
|
207
|
+
# - template: template to look for ('foo.bar' or 'foo.*' or '*.bar').
|
216
208
|
# return: a hash associating template and corresponding file.
|
217
209
|
def self.search_templates(template)
|
218
210
|
raise Bee::Util::BuildError.
|
@@ -257,8 +249,12 @@ module Bee
|
|
257
249
|
lines = file_cache(file)
|
258
250
|
@source = match_tabs(lines, lineno, "def")
|
259
251
|
@comment = preceding_comment(lines, lineno)
|
260
|
-
@defn = lines[lineno].strip.gsub(/^def\W+(
|
261
|
-
@
|
252
|
+
@defn = lines[lineno].strip.gsub(/^def\W+(.*)/){$1}
|
253
|
+
if @defn =~ /.*?\(.*?\)/
|
254
|
+
@params = @defn.gsub(/.*?\((.*?)\)/){$1}.split(',').map{|p| p.strip}
|
255
|
+
else
|
256
|
+
@params = []
|
257
|
+
end
|
262
258
|
end
|
263
259
|
|
264
260
|
private
|
@@ -333,6 +329,12 @@ module Bee
|
|
333
329
|
# be displayed on an internal error only). Include BuildErrorMixin to get
|
334
330
|
# a convenient way to raise such an error.
|
335
331
|
class BuildError < RuntimeError
|
332
|
+
|
333
|
+
# Last met target.
|
334
|
+
attr_accessor :target
|
335
|
+
# Last met task.
|
336
|
+
attr_accessor :task
|
337
|
+
|
336
338
|
end
|
337
339
|
|
338
340
|
# Build error mixin provides error() function to raise a BuildError.
|
@@ -344,7 +346,7 @@ module Bee
|
|
344
346
|
# Convenient method to raise a BuildError.
|
345
347
|
# - message: error message.
|
346
348
|
def error(message)
|
347
|
-
raise BuildError.new(message)
|
349
|
+
Kernel.raise BuildError.new(message)
|
348
350
|
end
|
349
351
|
|
350
352
|
end
|