autobuild 1.6.5 → 1.7.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +2 -2
- data/lib/autobuild/configurable.rb +1 -1
- data/lib/autobuild/environment.rb +156 -23
- data/lib/autobuild/import/archive.rb +62 -3
- data/lib/autobuild/importer.rb +46 -17
- data/lib/autobuild/package.rb +69 -7
- data/lib/autobuild/packages/autotools.rb +10 -6
- data/lib/autobuild/packages/cmake.rb +28 -5
- data/lib/autobuild/packages/genom.rb +4 -4
- data/lib/autobuild/packages/import.rb +1 -1
- data/lib/autobuild/packages/orogen.rb +3 -3
- data/lib/autobuild/parallel.rb +79 -34
- data/lib/autobuild/reporting.rb +95 -18
- data/lib/autobuild/subcommand.rb +25 -2
- data/lib/autobuild/version.rb +1 -1
- data/test/test_reporting.rb +55 -0
- metadata +19 -17
data/Rakefile
CHANGED
@@ -10,8 +10,8 @@ Utilrb::Rake.hoe do
|
|
10
10
|
self.email = %q{rock-dev@dfki.de}
|
11
11
|
|
12
12
|
self.extra_deps <<
|
13
|
-
['rake', '>= 0.
|
14
|
-
['utilrb', '>= 1.
|
13
|
+
['rake', '>= 0.7.0'] <<
|
14
|
+
['utilrb', '>= 1.3.3'] <<
|
15
15
|
['highline', '>= 0']
|
16
16
|
end
|
17
17
|
Rake.clear_tasks(/publish_docs/, /default/)
|
@@ -1,10 +1,51 @@
|
|
1
1
|
require 'set'
|
2
|
+
require 'rbconfig'
|
3
|
+
|
2
4
|
module Autobuild
|
3
5
|
@inherited_environment = Hash.new
|
4
6
|
@environment = Hash.new
|
5
7
|
@env_source_before = Set.new
|
6
8
|
@env_source_after = Set.new
|
7
9
|
|
10
|
+
@windows = RbConfig::CONFIG["host_os"] =~%r!(msdos|mswin|djgpp|mingw|[Ww]indows)!
|
11
|
+
def self.windows?
|
12
|
+
@windows
|
13
|
+
end
|
14
|
+
|
15
|
+
@macos = RbConfig::CONFIG["host_os"] = ~%r!([Dd]arwin)!
|
16
|
+
def self.macos?
|
17
|
+
@macos
|
18
|
+
end
|
19
|
+
|
20
|
+
ORIGINAL_ENV = Hash.new
|
21
|
+
ENV.each do |k, v|
|
22
|
+
ORIGINAL_ENV[k] = v
|
23
|
+
end
|
24
|
+
ENV_LIST_SEPARATOR =
|
25
|
+
if windows? then ';'
|
26
|
+
else ':'
|
27
|
+
end
|
28
|
+
SHELL_VAR_EXPANSION =
|
29
|
+
if windows? then "%%%s%%"
|
30
|
+
else "$%s"
|
31
|
+
end
|
32
|
+
SHELL_SET_COMMAND =
|
33
|
+
if windows? then "set %s=%s"
|
34
|
+
else "%s=%s"
|
35
|
+
end
|
36
|
+
SHELL_UNSET_COMMAND =
|
37
|
+
if windows? then "unset %s"
|
38
|
+
else "unset %s"
|
39
|
+
end
|
40
|
+
SHELL_EXPORT_COMMAND =
|
41
|
+
if windows? then "set %s"
|
42
|
+
else "export %s"
|
43
|
+
end
|
44
|
+
SHELL_SOURCE_SCRIPT =
|
45
|
+
if windows? then "%s"
|
46
|
+
else ". \"%s\""
|
47
|
+
end
|
48
|
+
|
8
49
|
class << self
|
9
50
|
# List of the environment that should be set before calling a subcommand
|
10
51
|
#
|
@@ -35,24 +76,100 @@ module Autobuild
|
|
35
76
|
attr_reader :env_source_after
|
36
77
|
end
|
37
78
|
|
38
|
-
#
|
39
|
-
#
|
79
|
+
# Resets the value of +name+ to its original value. If it is inherited from
|
80
|
+
# the
|
81
|
+
def self.env_reset(name = nil)
|
82
|
+
if name
|
83
|
+
environment.delete(name)
|
84
|
+
inherited_environment.delete(name)
|
85
|
+
env_init_from_env(name)
|
86
|
+
else
|
87
|
+
environment.keys.each do |name|
|
88
|
+
env_reset(name)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Unsets any value on the environment variable +name+, including inherited
|
94
|
+
# value.
|
95
|
+
#
|
96
|
+
# In a bourne shell, this would be equivalent to doing
|
97
|
+
#
|
98
|
+
# unset name
|
99
|
+
#
|
40
100
|
def self.env_clear(name = nil)
|
41
101
|
if name
|
42
102
|
environment[name] = nil
|
43
103
|
inherited_environment[name] = nil
|
104
|
+
env_update_var(name)
|
44
105
|
else
|
45
|
-
environment.
|
46
|
-
|
106
|
+
environment.keys.each do |name|
|
107
|
+
env_clear(name)
|
108
|
+
end
|
47
109
|
end
|
48
110
|
end
|
49
111
|
|
50
112
|
# Set a new environment variable
|
51
113
|
def self.env_set(name, *values)
|
52
|
-
|
114
|
+
env_reset(name)
|
53
115
|
env_add(name, *values)
|
54
116
|
end
|
55
117
|
|
118
|
+
@env_inherit = true
|
119
|
+
@env_inherited_variables = Set.new
|
120
|
+
|
121
|
+
# Returns true if the given environment variable must not be reset by the
|
122
|
+
# env.sh script, but that new values should simply be prepended to it.
|
123
|
+
#
|
124
|
+
# See Autoproj.env_inherit
|
125
|
+
def self.env_inherit?(name)
|
126
|
+
@env_inherit && @env_inherited_variables.include?(name)
|
127
|
+
end
|
128
|
+
|
129
|
+
# If true (the default), the environment variables that are marked as
|
130
|
+
# inherited will be inherited from the global environment (during the
|
131
|
+
# build as well as in the generated env.sh files)
|
132
|
+
#
|
133
|
+
# Otherwise, only the environment that is explicitely set in autobuild
|
134
|
+
# will be passed on to subcommands, and saved in the environment
|
135
|
+
# scripts.
|
136
|
+
def self.env_inherit=(value)
|
137
|
+
@env_inherit = value
|
138
|
+
inherited_environment.keys.each do |env_name|
|
139
|
+
env_init_from_env(env_name)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# Declare that the given environment variable must not be reset by the
|
144
|
+
# env.sh script, but that new values should simply be prepended to it.
|
145
|
+
#
|
146
|
+
# See Autoproj.env_inherit?
|
147
|
+
def self.env_inherit(*names)
|
148
|
+
@env_inherited_variables |= names
|
149
|
+
names.each do |env_name|
|
150
|
+
env_init_from_env(env_name)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.env_init_from_env(name)
|
155
|
+
if env_inherit?(name) && (parent_env = ORIGINAL_ENV[name])
|
156
|
+
inherited_environment[name] = parent_env.split(ENV_LIST_SEPARATOR)
|
157
|
+
else
|
158
|
+
inherited_environment[name] = Array.new
|
159
|
+
end
|
160
|
+
env_update_var(name)
|
161
|
+
end
|
162
|
+
|
163
|
+
def self.env_push(name, *values)
|
164
|
+
if current = environment[name]
|
165
|
+
current = current.dup
|
166
|
+
env_set(name, *values)
|
167
|
+
env_add(name, *current)
|
168
|
+
else
|
169
|
+
env_add(name, *values)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
56
173
|
# Adds a new value to an environment variable
|
57
174
|
def self.env_add(name, *values)
|
58
175
|
set = if environment.has_key?(name)
|
@@ -60,11 +177,7 @@ module Autobuild
|
|
60
177
|
end
|
61
178
|
|
62
179
|
if !inherited_environment.has_key?(name)
|
63
|
-
|
64
|
-
inherited_environment[name] = parent_env.split(':')
|
65
|
-
else
|
66
|
-
inherited_environment[name] = Array.new
|
67
|
-
end
|
180
|
+
env_init_from_env(name)
|
68
181
|
end
|
69
182
|
|
70
183
|
if !set
|
@@ -75,22 +188,38 @@ module Autobuild
|
|
75
188
|
|
76
189
|
values.concat(set)
|
77
190
|
@environment[name] = values
|
191
|
+
env_update_var(name)
|
192
|
+
end
|
78
193
|
|
79
|
-
|
80
|
-
|
194
|
+
def self.env_update_var(name)
|
195
|
+
if !environment[name] && !inherited_environment[name]
|
196
|
+
ENV.delete(name)
|
197
|
+
else
|
198
|
+
ENV[name] = ((environment[name] || []) + (inherited_environment[name] || [])).join(ENV_LIST_SEPARATOR)
|
199
|
+
end
|
81
200
|
end
|
82
201
|
|
83
|
-
def self.env_add_path(name,
|
84
|
-
oldpath = environment[name]
|
85
|
-
|
202
|
+
def self.env_add_path(name, *paths)
|
203
|
+
oldpath = environment[name] || Array.new
|
204
|
+
paths.reverse.each do |path|
|
205
|
+
next if oldpath.include?(path)
|
206
|
+
|
86
207
|
env_add(name, path)
|
208
|
+
oldpath << path
|
87
209
|
if name == 'RUBYLIB'
|
88
210
|
$LOAD_PATH.unshift path
|
89
211
|
end
|
90
212
|
end
|
213
|
+
end
|
91
214
|
|
92
|
-
|
93
|
-
|
215
|
+
def self.env_push_path(name, *values)
|
216
|
+
if current = environment[name]
|
217
|
+
current = current.dup
|
218
|
+
env_clear(name)
|
219
|
+
env_add_path(name, *values)
|
220
|
+
env_add_path(name, *current)
|
221
|
+
else
|
222
|
+
env_add_path(name, *values)
|
94
223
|
end
|
95
224
|
end
|
96
225
|
|
@@ -119,27 +248,31 @@ module Autobuild
|
|
119
248
|
# It also sources the files added by Autobuild.env_source_file
|
120
249
|
def self.export_env_sh(io)
|
121
250
|
@env_source_before.each do |path|
|
122
|
-
io.puts
|
251
|
+
io.puts SHELL_SOURCE_SCRIPT % path
|
123
252
|
end
|
124
253
|
|
125
254
|
variables = []
|
126
255
|
Autobuild.environment.each do |name, value|
|
127
256
|
variables << name
|
128
|
-
|
129
|
-
|
257
|
+
if value
|
258
|
+
shell_line = SHELL_SET_COMMAND % [name, value.join(ENV_LIST_SEPARATOR)]
|
259
|
+
else
|
260
|
+
shell_line = SHELL_UNSET_COMMAND % [name]
|
261
|
+
end
|
262
|
+
if env_inherit?(name)
|
130
263
|
if value.empty?
|
131
264
|
next
|
132
265
|
else
|
133
|
-
shell_line << "
|
266
|
+
shell_line << "#{ENV_LIST_SEPARATOR}$#{name}"
|
134
267
|
end
|
135
268
|
end
|
136
269
|
io.puts shell_line
|
137
270
|
end
|
138
271
|
variables.each do |var|
|
139
|
-
io.puts
|
272
|
+
io.puts SHELL_EXPORT_COMMAND % [var]
|
140
273
|
end
|
141
274
|
@env_source_after.each do |path|
|
142
|
-
io.puts
|
275
|
+
io.puts SHELL_SOURCE_SCRIPT % [path]
|
143
276
|
end
|
144
277
|
end
|
145
278
|
|
@@ -2,6 +2,15 @@ require 'autobuild/importer'
|
|
2
2
|
require 'open-uri'
|
3
3
|
require 'fileutils'
|
4
4
|
|
5
|
+
WINDOWS = RbConfig::CONFIG["host_os"] =~%r!(msdos|mswin|djgpp|mingw|[Ww]indows)!
|
6
|
+
if WINDOWS
|
7
|
+
require 'net/http'
|
8
|
+
require 'net/https'
|
9
|
+
require 'rubygems/package'
|
10
|
+
require 'zlib'
|
11
|
+
end
|
12
|
+
|
13
|
+
|
5
14
|
module Autobuild
|
6
15
|
class ArchiveImporter < Importer
|
7
16
|
# The tarball is not compressed
|
@@ -36,6 +45,47 @@ module Autobuild
|
|
36
45
|
|
37
46
|
def update_cached_file?; @options[:update_cached_file] end
|
38
47
|
|
48
|
+
|
49
|
+
def get_url_on_windows(url, filename)
|
50
|
+
uri = URI(url)
|
51
|
+
STDOUT.puts("Host: #{uri.host} Port: #{uri.port} url: #{url}")
|
52
|
+
|
53
|
+
http = Net::HTTP.new(uri.host,uri.port)
|
54
|
+
http.use_ssl = true if uri.port == 443
|
55
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE #Unsure, critical?, Review this
|
56
|
+
resp = http.get(uri.request_uri)
|
57
|
+
|
58
|
+
if resp.code == "301" or resp.code == "302"
|
59
|
+
get_url_on_windows(resp.header['location'],filename)
|
60
|
+
else
|
61
|
+
if(resp.message != 'OK')
|
62
|
+
raise "Could not get File from url \"#{url}\", got response #{resp.message} (#{resp.code})"
|
63
|
+
end
|
64
|
+
open(filename, "wb") do |file|
|
65
|
+
file.write(resp.body)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def extract_tar_on_windows(filename,target)
|
71
|
+
|
72
|
+
Gem::Package::TarReader.new(Zlib::GzipReader.open(filename)).each do |entry|
|
73
|
+
newname = File.join(target,entry.full_name.slice(entry.full_name.index('/'),entry.full_name.size))
|
74
|
+
if(entry.directory?)
|
75
|
+
FileUtils.mkdir_p(newname)
|
76
|
+
end
|
77
|
+
if(entry.file?)
|
78
|
+
dir = newname.slice(0,newname.rindex('/'))
|
79
|
+
if(!File.directory?(dir))
|
80
|
+
FileUtils.mkdir_p(dir)
|
81
|
+
end
|
82
|
+
open(newname, "wb") do |file|
|
83
|
+
file.write(entry.read)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
39
89
|
# Updates the downloaded file in cache only if it is needed
|
40
90
|
def update_cache(package)
|
41
91
|
do_update = false
|
@@ -73,7 +123,11 @@ module Autobuild
|
|
73
123
|
if do_update
|
74
124
|
FileUtils.mkdir_p(cachedir)
|
75
125
|
begin
|
76
|
-
|
126
|
+
if(WINDOWS)
|
127
|
+
get_url_on_windows(@url, "#{cachefile}.partial")
|
128
|
+
else
|
129
|
+
Subprocess.run(package, :import, Autobuild.tool('wget'), '-q', '-P', cachedir, @url, '-O', "#{cachefile}.partial")
|
130
|
+
end
|
77
131
|
rescue Exception
|
78
132
|
FileUtils.rm_f "#{cachefile}.partial"
|
79
133
|
raise
|
@@ -172,13 +226,18 @@ module Autobuild
|
|
172
226
|
if !@options[:no_subdirectory]
|
173
227
|
cmd << '--strip-components=1'
|
174
228
|
end
|
175
|
-
|
229
|
+
|
230
|
+
if(WINDOWS)
|
231
|
+
extract_tar_on_windows(cachefile,package.srcdir)
|
232
|
+
else
|
233
|
+
Subprocess.run(package, :import, Autobuild.tool('tar'), *cmd)
|
234
|
+
end
|
176
235
|
end
|
177
236
|
|
178
237
|
rescue OpenURI::HTTPError
|
179
238
|
raise Autobuild::Exception.new(package.name, :import)
|
180
239
|
rescue SubcommandFailed
|
181
|
-
|
240
|
+
FileUtils.rm_f cachefile
|
182
241
|
raise
|
183
242
|
end
|
184
243
|
end
|
data/lib/autobuild/importer.rb
CHANGED
@@ -87,12 +87,28 @@ class Importer
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def patches
|
90
|
-
|
91
|
-
@options[:patches]
|
92
|
-
|
93
|
-
[]
|
90
|
+
patches =
|
91
|
+
if @options[:patches].respond_to?(:to_ary)
|
92
|
+
@options[:patches]
|
93
|
+
elsif !@options[:patches]
|
94
|
+
[]
|
95
|
+
else
|
96
|
+
[[@options[:patches], 0]]
|
97
|
+
end
|
98
|
+
|
99
|
+
if patches.size == 2 && patches[0].respond_to?(:to_str) && patches[1].respond_to?(:to_int)
|
100
|
+
patches = [patches]
|
94
101
|
else
|
95
|
-
|
102
|
+
patches.map do |obj|
|
103
|
+
if obj.respond_to?(:to_str)
|
104
|
+
[obj, 0]
|
105
|
+
elsif obj.respond_to?(:to_ary)
|
106
|
+
obj
|
107
|
+
else
|
108
|
+
raise Arguments, "wrong patch specification #{obj.inspect}"
|
109
|
+
obj
|
110
|
+
end
|
111
|
+
end
|
96
112
|
end
|
97
113
|
end
|
98
114
|
|
@@ -139,7 +155,7 @@ class Importer
|
|
139
155
|
package.message "update failed in #{package.srcdir}, retrying (#{retry_count}/#{self.retry_count})"
|
140
156
|
retry
|
141
157
|
ensure
|
142
|
-
package.progress_done
|
158
|
+
package.progress_done "updated %s"
|
143
159
|
end
|
144
160
|
|
145
161
|
patch(package)
|
@@ -151,7 +167,7 @@ class Importer
|
|
151
167
|
end
|
152
168
|
|
153
169
|
def perform_checkout(package)
|
154
|
-
package.progress_start "checking out %s" do
|
170
|
+
package.progress_start "checking out %s", :done_message => 'checked out %s' do
|
155
171
|
retry_count = 0
|
156
172
|
begin
|
157
173
|
checkout(package)
|
@@ -226,23 +242,35 @@ class Importer
|
|
226
242
|
File.join(package.srcdir, "patches-autobuild-stamp")
|
227
243
|
end
|
228
244
|
|
229
|
-
def call_patch(package, reverse, file)
|
245
|
+
def call_patch(package, reverse, file, patch_level)
|
230
246
|
patch = Autobuild.tool('patch')
|
231
247
|
Dir.chdir(package.srcdir) do
|
232
|
-
Subprocess.run(package, :patch, patch,
|
248
|
+
Subprocess.run(package, :patch, patch, "-p#{patch_level}", (reverse ? '-R' : nil), '--forward', :input => file)
|
233
249
|
end
|
234
250
|
end
|
235
251
|
|
236
|
-
def apply(package, path); call_patch(package, false, path) end
|
237
|
-
def unapply(package, path); call_patch(package, true, path) end
|
252
|
+
def apply(package, path, patch_level = 0); call_patch(package, false, path, patch_level) end
|
253
|
+
def unapply(package, path, patch_level = 0); call_patch(package, true, path, patch_level) end
|
238
254
|
|
239
255
|
def currently_applied_patches(package)
|
240
256
|
patches_file = patchlist(package)
|
241
257
|
if !File.exists?(patches_file) then []
|
242
258
|
else
|
259
|
+
current_patches = []
|
243
260
|
File.open(patches_file) do |f|
|
244
|
-
f.readlines.
|
261
|
+
f.readlines.each do |line|
|
262
|
+
line = line.rstrip
|
263
|
+
if line =~ /^(.*)\s+(\d+)$/
|
264
|
+
path = $1
|
265
|
+
level = Integer($2)
|
266
|
+
else
|
267
|
+
path = line
|
268
|
+
level = 0
|
269
|
+
end
|
270
|
+
current_patches << [path, level]
|
271
|
+
end
|
245
272
|
end
|
273
|
+
current_patches
|
246
274
|
end
|
247
275
|
end
|
248
276
|
|
@@ -268,17 +296,18 @@ class Importer
|
|
268
296
|
end
|
269
297
|
|
270
298
|
while p = cur_patches.last
|
271
|
-
|
299
|
+
p, level = *p
|
300
|
+
unapply(package, p, level)
|
272
301
|
cur_patches.pop
|
273
302
|
end
|
274
303
|
|
275
|
-
patches.to_a.each do |p|
|
276
|
-
apply(package, p)
|
277
|
-
cur_patches << p
|
304
|
+
patches.to_a.each do |p, level|
|
305
|
+
apply(package, p, level)
|
306
|
+
cur_patches << [p, level]
|
278
307
|
end
|
279
308
|
ensure
|
280
309
|
File.open(patchlist(package), 'w+') do |f|
|
281
|
-
f.write(cur_patches.join("\n"))
|
310
|
+
f.write(cur_patches.map { |p, l| "#{p} #{l}" }.join("\n"))
|
282
311
|
end
|
283
312
|
end
|
284
313
|
|