autobuild 1.6.5 → 1.7.0.rc1
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/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
|
|