autobuild 1.8.3 → 1.9.0.b1
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.
- checksums.yaml +4 -4
- data/Manifest.txt +16 -7
- data/Rakefile +2 -0
- data/lib/autobuild/config.rb +21 -6
- data/lib/autobuild/configurable.rb +2 -2
- data/lib/autobuild/environment.rb +52 -27
- data/lib/autobuild/exceptions.rb +48 -22
- data/lib/autobuild/import/archive.rb +37 -16
- data/lib/autobuild/import/cvs.rb +26 -28
- data/lib/autobuild/import/darcs.rb +9 -8
- data/lib/autobuild/import/git.rb +324 -217
- data/lib/autobuild/import/hg.rb +6 -9
- data/lib/autobuild/import/svn.rb +190 -47
- data/lib/autobuild/importer.rb +80 -35
- data/lib/autobuild/package.rb +16 -35
- data/lib/autobuild/packages/autotools.rb +8 -8
- data/lib/autobuild/packages/cmake.rb +18 -12
- data/lib/autobuild/packages/genom.rb +1 -1
- data/lib/autobuild/packages/gnumake.rb +11 -12
- data/lib/autobuild/packages/orogen.rb +1 -1
- data/lib/autobuild/packages/ruby.rb +9 -5
- data/lib/autobuild/reporting.rb +10 -6
- data/lib/autobuild/subcommand.rb +110 -50
- data/lib/autobuild/test.rb +104 -0
- data/lib/autobuild/timestamps.rb +3 -3
- data/lib/autobuild/tools.rb +1 -1
- data/lib/autobuild/utility.rb +22 -10
- data/lib/autobuild/version.rb +1 -1
- data/test/data/gitrepo-with-extra-commit-and-tag.tar +0 -0
- data/test/data/gitrepo.tar +0 -0
- data/test/data/gitrepo/test +0 -0
- data/test/data/gitrepo/test2 +0 -0
- data/test/data/gitrepo/test3 +0 -0
- data/test/data/svnroot.tar +0 -0
- data/test/import/test_cvs.rb +51 -0
- data/test/import/test_git.rb +364 -0
- data/test/import/test_svn.rb +144 -0
- data/test/import/test_tar.rb +76 -0
- data/test/suite.rb +7 -0
- data/test/test_config.rb +1 -5
- data/test/test_environment.rb +88 -0
- data/test/test_reporting.rb +2 -14
- data/test/test_subcommand.rb +7 -22
- metadata +17 -14
- data/test/test_import_cvs.rb +0 -59
- data/test/test_import_svn.rb +0 -56
- data/test/test_import_tar.rb +0 -83
- data/test/tools.rb +0 -44
data/lib/autobuild/package.rb
CHANGED
@@ -127,6 +127,9 @@ module Autobuild
|
|
127
127
|
def updated?; !!@updated end
|
128
128
|
|
129
129
|
def initialize(spec = Hash.new)
|
130
|
+
@srcdir = @importdir = @logdir = nil
|
131
|
+
@update = nil
|
132
|
+
@failed = nil
|
130
133
|
@dependencies = Array.new
|
131
134
|
@provides = Array.new
|
132
135
|
@parallel_build_level = nil
|
@@ -187,7 +190,7 @@ module Autobuild
|
|
187
190
|
# target files so that all the build phases of this package gets
|
188
191
|
# retriggered. However, it should not clean the build products.
|
189
192
|
def prepare_for_forced_build
|
190
|
-
if File.
|
193
|
+
if File.exist?(installstamp)
|
191
194
|
FileUtils.rm_f installstamp
|
192
195
|
end
|
193
196
|
end
|
@@ -197,7 +200,7 @@ module Autobuild
|
|
197
200
|
def prepare_for_rebuild
|
198
201
|
prepare_for_forced_build
|
199
202
|
|
200
|
-
if File.
|
203
|
+
if File.exist?(installstamp)
|
201
204
|
FileUtils.rm_f installstamp
|
202
205
|
end
|
203
206
|
end
|
@@ -258,17 +261,22 @@ module Autobuild
|
|
258
261
|
end
|
259
262
|
|
260
263
|
# Call the importer if there is one. Autodetection of "provides" should
|
261
|
-
# be done there as well.
|
262
|
-
#
|
263
|
-
|
264
|
+
# be done there as well.
|
265
|
+
#
|
266
|
+
# (see Importer#import)
|
267
|
+
def import(options = Hash.new)
|
268
|
+
if !options.respond_to?(:to_hash)
|
269
|
+
options = Hash[only_local: options]
|
270
|
+
end
|
271
|
+
|
264
272
|
if @importer
|
265
|
-
@importer.import(self,
|
266
|
-
elsif
|
273
|
+
@importer.import(self, options)
|
274
|
+
elsif update?
|
267
275
|
message "%s: no importer defined, doing nothing"
|
268
276
|
end
|
269
277
|
|
270
278
|
# Add the dependencies declared in spec
|
271
|
-
depends_on
|
279
|
+
depends_on(*@spec_dependencies) if @spec_dependencies
|
272
280
|
update_environment
|
273
281
|
end
|
274
282
|
|
@@ -404,33 +412,6 @@ module Autobuild
|
|
404
412
|
task
|
405
413
|
end
|
406
414
|
|
407
|
-
module TaskExtension
|
408
|
-
attr_accessor :package
|
409
|
-
end
|
410
|
-
|
411
|
-
def source_tree(*args, &block)
|
412
|
-
task = Autobuild.source_tree(*args, &block)
|
413
|
-
task.extend TaskExtension
|
414
|
-
task.package = self
|
415
|
-
task
|
416
|
-
end
|
417
|
-
|
418
|
-
# Calls Rake to define a file task and then extends it with TaskExtension
|
419
|
-
def file(*args, &block)
|
420
|
-
task = super
|
421
|
-
task.extend TaskExtension
|
422
|
-
task.package = self
|
423
|
-
task
|
424
|
-
end
|
425
|
-
|
426
|
-
# Calls Rake to define a plain task and then extends it with TaskExtension
|
427
|
-
def task(*args, &block)
|
428
|
-
task = super
|
429
|
-
task.extend TaskExtension
|
430
|
-
task.package = self
|
431
|
-
task
|
432
|
-
end
|
433
|
-
|
434
415
|
def doc_dir=(value); doc_utility.source_dir = value end
|
435
416
|
def doc_dir; doc_utility.source_dir end
|
436
417
|
def doc_target_dir=(value); doc_utility.target_dir = value end
|
@@ -102,9 +102,9 @@ module Autobuild
|
|
102
102
|
end
|
103
103
|
|
104
104
|
if !programs.kind_of?(Hash)
|
105
|
-
programs = Array[*programs].inject({}) do |
|
106
|
-
|
107
|
-
|
105
|
+
programs = Array[*programs].inject({}) do |progs, spec|
|
106
|
+
progs[spec.first] = spec.last
|
107
|
+
progs
|
108
108
|
end
|
109
109
|
end
|
110
110
|
programs.each do |name, opt|
|
@@ -168,7 +168,7 @@ module Autobuild
|
|
168
168
|
# If it is not the case, remove it to force reconfiguration
|
169
169
|
configureflags.flatten!
|
170
170
|
force_reconfigure = false
|
171
|
-
if File.
|
171
|
+
if File.exist?(configurestamp)
|
172
172
|
output = IO.popen("#{configurestamp} --version").readlines.grep(/with options/).first.chomp
|
173
173
|
raise "invalid output of config.status --version" unless output =~ /with options "(.*)"$/
|
174
174
|
options = Shellwords.shellwords($1)
|
@@ -224,11 +224,11 @@ module Autobuild
|
|
224
224
|
end
|
225
225
|
using[:aclocal] = using[:autoconf] if using[:aclocal].nil?
|
226
226
|
if using[:automake].nil?
|
227
|
-
using[:automake] = File.
|
227
|
+
using[:automake] = File.exist?(File.join(srcdir, 'Makefile.am'))
|
228
228
|
end
|
229
229
|
|
230
230
|
if using[:libtool].nil?
|
231
|
-
using[:libtool] = File.
|
231
|
+
using[:libtool] = File.exist?(File.join(srcdir, 'ltmain.sh'))
|
232
232
|
end
|
233
233
|
end
|
234
234
|
|
@@ -237,7 +237,7 @@ module Autobuild
|
|
237
237
|
conffile = "#{srcdir}/configure"
|
238
238
|
if confsource
|
239
239
|
file conffile => confsource
|
240
|
-
elsif confext = %w{.ac .in}.find { |ext| File.
|
240
|
+
elsif confext = %w{.ac .in}.find { |ext| File.exist?("#{conffile}#{ext}") }
|
241
241
|
file conffile => "#{conffile}#{confext}"
|
242
242
|
else
|
243
243
|
raise PackageException.new(self, 'prepare'), "neither configure.ac nor configure.in present in #{srcdir}"
|
@@ -247,7 +247,7 @@ module Autobuild
|
|
247
247
|
isolate_errors do
|
248
248
|
in_dir(srcdir) do
|
249
249
|
if using[:autogen].nil?
|
250
|
-
using[:autogen] = %w{autogen autogen.sh}.find { |f| File.
|
250
|
+
using[:autogen] = %w{autogen autogen.sh}.find { |f| File.exist?(File.join(srcdir, f)) }
|
251
251
|
end
|
252
252
|
|
253
253
|
autodetect_needed_stages
|
@@ -76,13 +76,14 @@ module Autobuild
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def define(name, value)
|
79
|
-
@defines[name] =
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
79
|
+
@defines[name] =
|
80
|
+
if value.respond_to?(:to_str)
|
81
|
+
value.to_str
|
82
|
+
elsif value
|
83
|
+
'ON'
|
84
|
+
else
|
85
|
+
'OFF'
|
86
|
+
end
|
86
87
|
end
|
87
88
|
|
88
89
|
DOXYGEN_ACCEPTED_VARIABLES = {
|
@@ -265,13 +266,13 @@ module Autobuild
|
|
265
266
|
# but no Makefile.
|
266
267
|
#
|
267
268
|
# Delete the CMakeCache to force reconfiguration
|
268
|
-
if !File.
|
269
|
+
if !File.exist?( File.join(builddir, 'Makefile') )
|
269
270
|
FileUtils.rm_f cmake_cache
|
270
271
|
end
|
271
272
|
|
272
273
|
doc_utility.source_ref_dir = builddir
|
273
274
|
|
274
|
-
if File.
|
275
|
+
if File.exist?(cmake_cache)
|
275
276
|
all_defines = defines.dup
|
276
277
|
all_defines['CMAKE_INSTALL_PREFIX'] = prefix
|
277
278
|
all_defines['CMAKE_MODULE_PATH'] = "#{CMake.module_path.join(";")}"
|
@@ -361,24 +362,24 @@ module Autobuild
|
|
361
362
|
|
362
363
|
# Do the build in builddir
|
363
364
|
def build
|
365
|
+
current_message = String.new
|
364
366
|
in_dir(builddir) do
|
365
367
|
progress_start "building %s" do
|
366
368
|
if always_reconfigure || !File.file?('Makefile')
|
367
369
|
Subprocess.run(self, 'build', Autobuild.tool(:cmake), '.')
|
368
370
|
end
|
369
371
|
|
370
|
-
current_message = String.new
|
371
372
|
warning_count = 0
|
372
373
|
Autobuild.make_subcommand(self, 'build') do |line|
|
373
374
|
needs_display = false
|
374
375
|
if line =~ /\[\s*(\d+)%\]/
|
375
376
|
progress "building %s (#{Integer($1)}%)"
|
376
|
-
elsif line !~ /^(?:Linking|Scanning|Building|Built)/
|
377
|
+
elsif line !~ /^(?:Generating|Linking|Scanning|Building|Built)/
|
377
378
|
if line =~ /warning/
|
378
379
|
warning_count += 1
|
379
380
|
end
|
380
381
|
if show_make_messages?
|
381
|
-
current_message += line
|
382
|
+
current_message += line + "\n"
|
382
383
|
needs_display = true
|
383
384
|
end
|
384
385
|
end
|
@@ -400,6 +401,11 @@ module Autobuild
|
|
400
401
|
end
|
401
402
|
end
|
402
403
|
Autobuild.touch_stamp(buildstamp)
|
404
|
+
rescue ::Exception
|
405
|
+
current_message.split("\n").each do |l|
|
406
|
+
message "%s: #{l}", :magenta
|
407
|
+
end
|
408
|
+
raise
|
403
409
|
end
|
404
410
|
|
405
411
|
# Install the result in prefix
|
@@ -117,7 +117,7 @@ module Autobuild
|
|
117
117
|
|
118
118
|
# Check that the module has been generated with the same flags
|
119
119
|
genom_mk = "#{srcdir}/autoconf/genom.mk"
|
120
|
-
if File.
|
120
|
+
if File.exist?(genom_mk)
|
121
121
|
contents = File.open(genom_mk).readlines
|
122
122
|
old_file = contents.find { |l| l =~ /^GENFILE/ }.gsub('GENFILE=', '').strip
|
123
123
|
old_flags = Shellwords.shellwords(
|
@@ -18,31 +18,30 @@ module Autobuild
|
|
18
18
|
make_is_gnumake?(path)
|
19
19
|
end
|
20
20
|
|
21
|
-
def self.
|
21
|
+
def self.invoke_make_parallel(pkg, cmd_path = Autobuild.tool(:make))
|
22
22
|
reserved = nil
|
23
|
-
cmd_path = Autobuild.tool(:make)
|
24
|
-
cmd = [cmd_path]
|
25
23
|
if make_has_j_option?(cmd_path) && pkg.parallel_build_level != 1
|
26
24
|
if manager = Autobuild.parallel_task_manager
|
27
25
|
job_server = manager.job_server
|
28
26
|
if !make_has_gnumake_jobserver?(cmd_path) || (pkg.parallel_build_level != Autobuild.parallel_build_level)
|
29
27
|
reserved = pkg.parallel_build_level
|
30
28
|
job_server.get(reserved - 1) # We already have one token taken by autobuild itself
|
31
|
-
|
32
|
-
else
|
33
|
-
cmd << "--jobserver-fds=#{job_server.rio.fileno},#{job_server.wio.fileno}" << "-j"
|
29
|
+
yield("-j#{pkg.parallel_build_level}")
|
34
30
|
end
|
35
|
-
|
36
|
-
cmd << "-j#{pkg.parallel_build_level}"
|
31
|
+
yield("--jobserver-fds=#{job_server.rio.fileno},#{job_server.wio.fileno}", "-j")
|
37
32
|
end
|
33
|
+
yield("-j#{pkg.parallel_build_level}")
|
34
|
+
else yield
|
38
35
|
end
|
39
|
-
|
40
|
-
cmd.concat(options)
|
41
|
-
Subprocess.run(pkg, phase, *cmd, &block)
|
42
|
-
|
43
36
|
ensure
|
44
37
|
if reserved
|
45
38
|
job_server.put(reserved)
|
46
39
|
end
|
47
40
|
end
|
41
|
+
|
42
|
+
def self.make_subcommand(pkg, phase, *options, &block)
|
43
|
+
invoke_make_parallel(pkg, Autobuild.tool(:make)) do |*make_parallel_options|
|
44
|
+
Subprocess.run(pkg, phase, Autobuild.tool(:make), *make_parallel_options, *options, &block)
|
45
|
+
end
|
46
|
+
end
|
48
47
|
end
|
@@ -47,6 +47,14 @@ module Autobuild
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
+
def invoke_rake(setup_task = rake_setup_task)
|
51
|
+
if setup_task && File.file?(File.join(srcdir, 'Rakefile'))
|
52
|
+
Autobuild::Subprocess.run self, 'post-install',
|
53
|
+
Autobuild.tool_in_path('ruby'), '-S', Autobuild.tool('rake'), setup_task,
|
54
|
+
:working_directory => srcdir
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
50
58
|
def install
|
51
59
|
progress_start "setting up Ruby package %s", :done_message => 'set up Ruby package %s' do
|
52
60
|
Autobuild.update_environment srcdir
|
@@ -57,11 +65,7 @@ module Autobuild
|
|
57
65
|
Autobuild.env_add_path 'RUBYLIB', libdir
|
58
66
|
end
|
59
67
|
|
60
|
-
|
61
|
-
Autobuild::Subprocess.run self, 'post-install',
|
62
|
-
Autobuild.tool_in_path('ruby'), '-S', Autobuild.tool('rake'), rake_setup_task,
|
63
|
-
:working_directory => srcdir
|
64
|
-
end
|
68
|
+
invoke_rake
|
65
69
|
end
|
66
70
|
super
|
67
71
|
end
|
data/lib/autobuild/reporting.rb
CHANGED
@@ -34,13 +34,17 @@ module Autobuild
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def self.display_message(*args)
|
37
|
+
io = STDOUT
|
38
|
+
if args.last.kind_of?(IO)
|
39
|
+
io = args.pop
|
40
|
+
end
|
37
41
|
msg =
|
38
42
|
if args.empty? then ""
|
39
43
|
else "#{color(*args)}"
|
40
44
|
end
|
41
45
|
|
42
46
|
if !Autobuild.progress_display_enabled?
|
43
|
-
puts msg
|
47
|
+
io.puts msg
|
44
48
|
return
|
45
49
|
end
|
46
50
|
|
@@ -50,7 +54,7 @@ module Autobuild
|
|
50
54
|
end
|
51
55
|
|
52
56
|
if !silent?
|
53
|
-
puts "\r#{msg}#{" " * [size - msg.size, 0].max}"
|
57
|
+
io.puts "\r#{msg}#{" " * [size - msg.size, 0].max}"
|
54
58
|
if @last_progress_msg
|
55
59
|
print "#{@last_progress_msg}"
|
56
60
|
end
|
@@ -64,12 +68,12 @@ module Autobuild
|
|
64
68
|
|
65
69
|
# Displays an error message
|
66
70
|
def self.error(message = "")
|
67
|
-
message(" ERROR: #{message}", :red, :bold)
|
71
|
+
message(" ERROR: #{message}", :red, :bold, STDERR)
|
68
72
|
end
|
69
73
|
|
70
74
|
# Displays a warning message
|
71
75
|
def self.warn(message = "", *style)
|
72
|
-
message(" WARN: #{message}", :magenta, *style)
|
76
|
+
message(" WARN: #{message}", :magenta, *style, STDERR)
|
73
77
|
end
|
74
78
|
|
75
79
|
# @return [Boolean] true if there is some progress messages for the given
|
@@ -102,7 +106,7 @@ module Autobuild
|
|
102
106
|
progress(key, *options[:done_message])
|
103
107
|
end
|
104
108
|
progress_done(key, true)
|
105
|
-
rescue Exception
|
109
|
+
rescue Exception
|
106
110
|
progress_done(key, false)
|
107
111
|
raise
|
108
112
|
end
|
@@ -335,7 +339,7 @@ module Autobuild
|
|
335
339
|
## Display using stdout
|
336
340
|
class StdoutReporter < Reporter
|
337
341
|
def error(error)
|
338
|
-
puts "Build failed: #{error}"
|
342
|
+
STDERR.puts "Build failed: #{error}"
|
339
343
|
end
|
340
344
|
def success
|
341
345
|
puts "Build finished successfully at #{Time.now}"
|
data/lib/autobuild/subcommand.rb
CHANGED
@@ -39,11 +39,22 @@ module Autobuild
|
|
39
39
|
reset_statistics
|
40
40
|
|
41
41
|
@parallel_build_level = nil
|
42
|
+
@displayed_error_line_count = 10
|
42
43
|
class << self
|
43
44
|
# Sets the level of parallelism during the build
|
44
45
|
#
|
45
46
|
# See #parallel_build_level for detailed information
|
46
47
|
attr_writer :parallel_build_level
|
48
|
+
|
49
|
+
# set/get a value how much log lines should be displayed on errors
|
50
|
+
# this may be an integer or 'ALL' (which will be translated to -1)
|
51
|
+
# this is not using an attr_accessor to be able to validate the values
|
52
|
+
def displayed_error_line_count=(value)
|
53
|
+
@displayed_error_line_count = validate_displayed_error_line_count(value)
|
54
|
+
end
|
55
|
+
def displayed_error_line_count
|
56
|
+
@displayed_error_line_count
|
57
|
+
end
|
47
58
|
|
48
59
|
# Returns the number of processes that can run in parallel during the
|
49
60
|
# build. This is a system-wide value that can be overriden in a
|
@@ -121,31 +132,82 @@ module Autobuild
|
|
121
132
|
|
122
133
|
@processor_count
|
123
134
|
end
|
135
|
+
|
136
|
+
def self.validate_displayed_error_line_count(lines)
|
137
|
+
if lines == 'ALL'
|
138
|
+
return Float::INFINITY
|
139
|
+
elsif lines.to_i > 0
|
140
|
+
return lines.to_i
|
141
|
+
end
|
142
|
+
raise ConfigError, 'Autobuild.displayed_error_line_count can only be a positive integer or \'ALL\''
|
143
|
+
end
|
144
|
+
|
124
145
|
end
|
125
146
|
|
126
147
|
|
127
148
|
module Autobuild::Subprocess
|
128
149
|
class Failed < Exception
|
150
|
+
def retry?; @retry end
|
129
151
|
attr_reader :status
|
130
|
-
|
152
|
+
|
153
|
+
def initialize(status, do_retry)
|
131
154
|
@status = status
|
155
|
+
@retry = do_retry
|
132
156
|
end
|
133
157
|
end
|
134
158
|
|
135
159
|
CONTROL_COMMAND_NOT_FOUND = 1
|
136
160
|
CONTROL_UNEXPECTED = 2
|
137
161
|
CONTROL_INTERRUPT = 3
|
162
|
+
|
163
|
+
# Run a subcommand and return its standard output
|
164
|
+
#
|
165
|
+
# The command's standard and error outputs, as well as the full command line
|
166
|
+
# and an environment dump are saved in a log file in either the valure
|
167
|
+
# returned by target#logdir, or Autobuild.logdir if the target does not
|
168
|
+
# respond to #logdir.
|
169
|
+
#
|
170
|
+
# The subprocess priority is controlled by Autobuild.nice
|
171
|
+
#
|
172
|
+
# @param [String,(#name,#logdir,#working_directory)] target the target we
|
173
|
+
# run the subcommand for. In general, it will be a Package object (run from
|
174
|
+
# Package#run)
|
175
|
+
# @param [String] phase in which build phase this subcommand is executed
|
176
|
+
# @param [Array<String>] the command itself
|
177
|
+
# @yieldparam [String] line if a block is given, each output line from the
|
178
|
+
# command's standard output are yield to it. This is meant for progress
|
179
|
+
# display, and is disabled if Autobuild.verbose is set.
|
180
|
+
# @param [Hash] options
|
181
|
+
# @option options [String] :working_directory the directory in which the
|
182
|
+
# command should be started. If nil, runs in the current directory. The
|
183
|
+
# default is to either use the value returned by #working_directory on
|
184
|
+
# {target} if it responds to it, or nil.
|
185
|
+
# @option options [Boolean] :retry (false) controls whether a failure to
|
186
|
+
# execute this command should be retried by autobuild retry mechanisms (i.e.
|
187
|
+
# in the importers) or not. {run} will not retry the command by itself, it
|
188
|
+
# is passed as a hint for error handling clauses about whether the error
|
189
|
+
# should be retried or not
|
190
|
+
# @option options [Array<IO>] :input_streams list of input streams that
|
191
|
+
# should be fed to the command standard input. If a file needs to be given,
|
192
|
+
# the :input argument can be used as well as a shortcut
|
193
|
+
# @option options [String] :input the path to a file whose content should be
|
194
|
+
# fed to the command standard input
|
195
|
+
# @return [String] the command standard output
|
138
196
|
def self.run(target, phase, *command)
|
139
197
|
STDOUT.sync = true
|
140
198
|
|
141
199
|
input_streams = []
|
142
|
-
options = Hash
|
200
|
+
options = Hash[retry: false]
|
143
201
|
if command.last.kind_of?(Hash)
|
144
202
|
options = command.pop
|
145
203
|
options = Kernel.validate_options options,
|
146
|
-
:
|
204
|
+
input: nil, working_directory: nil, retry: false,
|
205
|
+
input_streams: []
|
147
206
|
if options[:input]
|
148
|
-
input_streams
|
207
|
+
input_streams << File.open(options[:input])
|
208
|
+
end
|
209
|
+
if options[:input_streams]
|
210
|
+
input_streams += options[:input_streams]
|
149
211
|
end
|
150
212
|
end
|
151
213
|
|
@@ -186,6 +248,7 @@ module Autobuild::Subprocess
|
|
186
248
|
end
|
187
249
|
|
188
250
|
Autobuild.register_logfile(logname)
|
251
|
+
subcommand_output = Array.new
|
189
252
|
|
190
253
|
status = File.open(logname, open_flag) do |logfile|
|
191
254
|
if Autobuild.keep_oldlogs
|
@@ -207,26 +270,20 @@ module Autobuild::Subprocess
|
|
207
270
|
if !input_streams.empty?
|
208
271
|
pread, pwrite = IO.pipe # to feed subprocess stdin
|
209
272
|
end
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
273
|
+
|
274
|
+
outread, outwrite = IO.pipe
|
275
|
+
outread.sync = true
|
276
|
+
outwrite.sync = true
|
277
|
+
|
215
278
|
cread, cwrite = IO.pipe # to control that exec goes well
|
216
279
|
|
217
280
|
if Autobuild.windows?
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
result=$?.success?
|
224
|
-
if(!result)
|
225
|
-
error = Autobuild::SubcommandFailed.new(target, command.join(" "), logname, "Systemcall")
|
226
|
-
error.phase = phase
|
227
|
-
raise error
|
281
|
+
Dir.chdir(options[:working_directory]) do
|
282
|
+
if !system(*command)
|
283
|
+
raise Failed.new($?.exitstatus, nil),
|
284
|
+
"'#{command.join(' ')}' returned status #{status.exitstatus}"
|
285
|
+
end
|
228
286
|
end
|
229
|
-
Dir.chdir(olddir)
|
230
287
|
return
|
231
288
|
end
|
232
289
|
|
@@ -278,13 +335,12 @@ module Autobuild::Subprocess
|
|
278
335
|
if !input_streams.empty?
|
279
336
|
pread.close
|
280
337
|
begin
|
281
|
-
input_streams.each do |
|
282
|
-
|
283
|
-
instream.each_line { |line| pwrite.write(line) }
|
284
|
-
end
|
338
|
+
input_streams.each do |instream|
|
339
|
+
instream.each_line { |line| pwrite.write(line) }
|
285
340
|
end
|
286
341
|
rescue Errno::ENOENT => e
|
287
|
-
raise Failed.new,
|
342
|
+
raise Failed.new(nil, false),
|
343
|
+
"cannot open input files: #{e.message}", retry: false
|
288
344
|
end
|
289
345
|
pwrite.close
|
290
346
|
end
|
@@ -296,43 +352,45 @@ module Autobuild::Subprocess
|
|
296
352
|
# An error occured
|
297
353
|
value = value.unpack('I').first
|
298
354
|
if value == CONTROL_COMMAND_NOT_FOUND
|
299
|
-
raise Failed.new,
|
355
|
+
raise Failed.new(nil, false),
|
356
|
+
"command '#{command.first}' not found"
|
300
357
|
elsif value == CONTROL_INTERRUPT
|
301
358
|
raise Interrupt, "command '#{command.first}': interrupted by user"
|
302
359
|
else
|
303
|
-
raise Failed.new,
|
360
|
+
raise Failed.new(nil, false),
|
361
|
+
"something unexpected happened"
|
304
362
|
end
|
305
363
|
end
|
306
364
|
|
307
365
|
# If the caller asked for process output, provide it to him
|
308
366
|
# line-by-line.
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
end
|
367
|
+
outwrite.close
|
368
|
+
outread.each_line do |line|
|
369
|
+
line.force_encoding('BINARY')
|
370
|
+
line = line.chomp
|
371
|
+
subcommand_output << line
|
372
|
+
|
373
|
+
if Autobuild.verbose
|
374
|
+
STDOUT.puts line
|
375
|
+
end
|
376
|
+
logfile.puts line
|
377
|
+
# Do not yield the line if Autobuild.verbose is true, as it
|
378
|
+
# would mix the progress output with the actual command
|
379
|
+
# output. Assume that if the user wants the command output,
|
380
|
+
# the autobuild progress output is unnecessary
|
381
|
+
if !Autobuild.verbose && block_given?
|
382
|
+
yield(line)
|
326
383
|
end
|
327
|
-
outread.close
|
328
384
|
end
|
385
|
+
outread.close
|
329
386
|
|
330
|
-
|
387
|
+
_, childstatus = Process.wait2(pid)
|
331
388
|
childstatus
|
332
389
|
end
|
333
390
|
|
334
391
|
if !status.exitstatus || status.exitstatus > 0
|
335
|
-
raise Failed.new(status.exitstatus
|
392
|
+
raise Failed.new(status.exitstatus, nil),
|
393
|
+
"'#{command.join(' ')}' returned status #{status.exitstatus}"
|
336
394
|
end
|
337
395
|
|
338
396
|
duration = Time.now - start_time
|
@@ -345,14 +403,16 @@ module Autobuild::Subprocess
|
|
345
403
|
if target.respond_to?(:add_stat)
|
346
404
|
target.add_stat(phase, duration)
|
347
405
|
end
|
406
|
+
subcommand_output
|
348
407
|
|
349
408
|
rescue Failed => e
|
350
|
-
error = Autobuild::SubcommandFailed.new(target, command.join(" "), logname, e.status)
|
409
|
+
error = Autobuild::SubcommandFailed.new(target, command.join(" "), logname, e.status, subcommand_output)
|
410
|
+
error.retry = if e.retry?.nil? then options[:retry]
|
411
|
+
else e.retry?
|
412
|
+
end
|
351
413
|
error.phase = phase
|
352
414
|
raise error, e.message
|
353
415
|
end
|
354
416
|
|
355
417
|
end
|
356
418
|
|
357
|
-
|
358
|
-
|