autobuild 1.5.61 → 1.6.0.b1

Sign up to get free protection for your applications and to get access to all the features.
data/Changes.txt CHANGED
@@ -1,3 +1,10 @@
1
+ == Version 1.6.0
2
+ * implement cross-package parallelism. Autobuild is now able to build packages
3
+ in parallel when parallel_build_level is greater than 1, better distributing
4
+ the workload. Additionally, if GNUmake is in use, this interfaces with the
5
+ GNUmake job server mechanism to allow the different make jobs to dynamically
6
+ distribute jobs among themselves (and with the main autoproj process)
7
+
1
8
  == Version 1.5.61
2
9
  * orogen: fix regeneration logic. Autobuild would not generate an oroGen project
3
10
  if a type definition file contained in the orogen package changed.
data/lib/autobuild.rb CHANGED
@@ -27,4 +27,5 @@ require 'autobuild/pkgconfig'
27
27
  require 'autobuild/reporting'
28
28
  require 'autobuild/subcommand'
29
29
  require 'autobuild/timestamps'
30
+ require 'autobuild/parallel'
30
31
 
@@ -281,8 +281,15 @@ module Autobuild
281
281
 
282
282
  task "#{buildname}-#{phase}" => targets
283
283
  end
284
- phases.each do |phase|
285
- Rake::Task["#{buildname}-#{phase}"].invoke
284
+
285
+ begin
286
+ invoker = Autobuild::RakeTaskParallelism.new
287
+ Autobuild.parallel_task_manager = invoker
288
+ phases.each do |phase|
289
+ invoker.invoke_parallel([Rake::Task["#{buildname}-#{phase}"]])
290
+ end
291
+ ensure
292
+ Autobuild.parallel_task_manager = nil
286
293
  end
287
294
  end
288
295
  end
@@ -90,6 +90,7 @@ module Autobuild
90
90
  isolate_errors do
91
91
  ensure_dependencies_installed
92
92
  configure
93
+ progress_done # Safety net for forgotten progress_done calls
93
94
  end
94
95
  end
95
96
  task "#{name}-prepare" => configurestamp
@@ -98,6 +99,7 @@ module Autobuild
98
99
  isolate_errors do
99
100
  ensure_dependencies_installed
100
101
  build
102
+ progress_done # Safety net for forgotten progress_done calls
101
103
  end
102
104
  end
103
105
  task "#{name}-build" => buildstamp
@@ -327,7 +327,7 @@ module Autobuild
327
327
  if detached_head?
328
328
  status_to_remote = merge_status(target_commit, fetch_commit)
329
329
  if status_to_remote.status != Status::UP_TO_DATE
330
- package.progress " the package is on a detached HEAD because of commit pinning"
330
+ package.message " the package is on a detached HEAD because of commit pinning"
331
331
  return
332
332
  end
333
333
  else
@@ -343,12 +343,12 @@ module Autobuild
343
343
  if local_branch
344
344
  status_to_branch = merge_status(target_commit, local_branch)
345
345
  if status_to_branch.status == Status::UP_TO_DATE # Checkout the branch
346
- package.progress " checking out specific commit %s for %s. It will checkout branch %s." % [target_commit.to_s, package.name, local_branch]
346
+ package.message " checking out specific commit %s for %s. It will checkout branch %s." % [target_commit.to_s, package.name, local_branch]
347
347
  Subprocess.run(package, :import, Autobuild.tool('git'), 'checkout', local_branch)
348
348
  return
349
349
  end
350
350
  end
351
- package.progress " checking out specific commit %s for %s. This will create a detached HEAD." % [target_commit.to_s, package.name]
351
+ package.message " checking out specific commit %s for %s. This will create a detached HEAD." % [target_commit.to_s, package.name]
352
352
  Subprocess.run(package, :import, Autobuild.tool('git'), 'checkout', target_commit)
353
353
  return
354
354
  end
@@ -362,10 +362,10 @@ module Autobuild
362
362
  # Check if the target branch already exists. If it is the
363
363
  # case, check it out. Otherwise, create it.
364
364
  if system("git", "show-ref", "--verify", "--quiet", "refs/heads/#{local_branch}")
365
- package.progress " switching branch of %s to %s" % [package.name, local_branch]
365
+ package.message " switching branch of %s to %s" % [package.name, local_branch]
366
366
  Subprocess.run(package, :import, Autobuild.tool('git'), 'checkout', local_branch)
367
367
  else
368
- package.progress " checking out branch %s for %s" % [local_branch, package.name]
368
+ package.message " checking out branch %s for %s" % [local_branch, package.name]
369
369
  Subprocess.run(package, :import, Autobuild.tool('git'), 'checkout', '-b', local_branch, "FETCH_HEAD")
370
370
  end
371
371
  end
@@ -403,7 +403,7 @@ module Autobuild
403
403
  if commit || tag
404
404
  status = merge_status(commit || tag)
405
405
  if status.status != Status::UP_TO_DATE
406
- package.progress " checking out specific commit for %s. This will create a detached HEAD." % [package.name]
406
+ package.message " checking out specific commit for %s. This will create a detached HEAD." % [package.name]
407
407
  Subprocess.run(package, :import, Autobuild.tool('git'), 'checkout', commit || tag)
408
408
  end
409
409
  else
@@ -85,9 +85,10 @@ class Importer
85
85
  patch(package, kept_patches)
86
86
  end
87
87
 
88
- package.progress "updating %s"
89
- update(package)
90
- patch(package)
88
+ package.progress_start "updating %s" do
89
+ update(package)
90
+ patch(package)
91
+ end
91
92
  package.updated = true
92
93
  rescue Interrupt
93
94
  raise
@@ -104,7 +105,7 @@ class Importer
104
105
  return fallback(original_error, package, :import, package)
105
106
  end
106
107
 
107
- package.progress "update failed and some patches are applied, retrying after removing all patches first"
108
+ package.message "update failed and some patches are applied, retrying after removing all patches first"
108
109
  begin
109
110
  patch(package, [])
110
111
 
@@ -118,9 +119,10 @@ class Importer
118
119
  end
119
120
 
120
121
  begin
121
- package.progress "updating %s"
122
- update(package)
123
- patch(package)
122
+ package.progress_start "updating %s" do
123
+ update(package)
124
+ patch(package)
125
+ end
124
126
  package.updated = true
125
127
  rescue Interrupt
126
128
  raise
@@ -130,15 +132,16 @@ class Importer
130
132
  end
131
133
 
132
134
  def perform_checkout(package)
133
- package.progress "checking out %s"
134
- checkout(package)
135
- patch(package)
135
+ package.progress_start "checking out %s" do
136
+ checkout(package)
137
+ patch(package)
138
+ end
136
139
  package.updated = true
137
140
  rescue Autobuild::Exception => e
138
141
  FileUtils.rm_rf package.srcdir
139
142
  fallback(e, package, :import, package)
140
143
  rescue ::Exception
141
- package.progress "checkout of %s failed, deleting the source directory #{package.srcdir}"
144
+ package.message "checkout of %s failed, deleting the source directory #{package.srcdir}"
142
145
  FileUtils.rm_rf package.srcdir
143
146
  raise
144
147
  end
@@ -222,11 +225,11 @@ class Importer
222
225
  apply_count = (patches - cur_patches).size
223
226
  unapply_count = (cur_patches - patches).size
224
227
  if apply_count > 0 && unapply_count > 0
225
- package.progress "patching %s: applying #{apply_count} and unapplying #{unapply_count} patch(es)"
228
+ package.message "patching %s: applying #{apply_count} and unapplying #{unapply_count} patch(es)"
226
229
  elsif apply_count > 0
227
- package.progress "patching %s: applying #{apply_count} patch(es)"
230
+ package.message "patching %s: applying #{apply_count} patch(es)"
228
231
  else
229
- package.progress "patching %s: unapplying #{unapply_count} patch(es)"
232
+ package.message "patching %s: unapplying #{unapply_count} patch(es)"
230
233
  end
231
234
 
232
235
  while p = cur_patches.last
@@ -108,6 +108,7 @@ module Autobuild
108
108
  @statistics = Hash.new
109
109
  @failures = Array.new
110
110
  @post_install_blocks = Array.new
111
+ @in_dir_stack = Array.new
111
112
 
112
113
  if Hash === spec
113
114
  name, depends = spec.to_a.first
@@ -215,9 +216,9 @@ module Autobuild
215
216
  if lines.empty?
216
217
  lines = ["unknown error"]
217
218
  end
218
- progress(lines.shift, :red, :bold)
219
+ message(lines.shift, :red, :bold)
219
220
  lines.each do |line|
220
- progress(line)
221
+ message(line)
221
222
  end
222
223
  nil
223
224
  else
@@ -235,7 +236,7 @@ module Autobuild
235
236
  if @importer
236
237
  @importer.import(self)
237
238
  elsif Autobuild.do_update
238
- progress "%s: no importer defined, doing nothing"
239
+ message "%s: no importer defined, doing nothing"
239
240
  end
240
241
 
241
242
  # Add the dependencies declared in spec
@@ -264,46 +265,54 @@ module Autobuild
264
265
  task "#{name}-build" => installstamp
265
266
  end
266
267
 
268
+ def process_formatting_string(msg)
269
+ msg % [name]
270
+ rescue ArgumentError => e
271
+ msg
272
+ end
273
+
267
274
  # Display a progress message. %s in the string is replaced by the
268
275
  # package name
269
- def progress(*args)
276
+ def message(*args)
270
277
  if !args.empty?
271
- begin args[0] = args[0] % [name]
272
- rescue ArgumentError
273
- # Don't try to format strings that can't be formatted
274
- end
275
-
276
- Autobuild.progress(*args)
277
- else
278
- Autobuild.progress
278
+ args[0] = " #{process_formatting_string(args[0])}"
279
279
  end
280
+ Autobuild.message(*args)
280
281
  end
281
282
 
282
- # Display a progress message, and later on update it with a progress
283
- # value. %s in the string is replaced by the package name
284
- def progress_with_value(*args)
285
- if !args.empty?
286
- args[0] = args[0] % [name]
287
- Autobuild.progress_with_value(*args)
288
- else
289
- Autobuild.progress_with_value
283
+ def progress_start(*args, &block)
284
+ args[0] = process_formatting_string(args[0])
285
+ if args.last.kind_of?(Hash)
286
+ options, raw_options = Kernel.filter_options args.last, :done_message
287
+ if options[:done_message]
288
+ options[:done_message] = process_formatting_string(options[:done_message])
289
+ end
290
+ args[-1] = options.merge(raw_options)
290
291
  end
292
+
293
+ Autobuild.progress_start(self, *args, &block)
291
294
  end
292
295
 
293
- def progress_value(value)
294
- Autobuild.progress_value(value)
296
+ def progress(*args)
297
+ args[0] = process_formatting_string(args[0])
298
+ Autobuild.progress(self, *args)
299
+ end
300
+
301
+ def progress_done
302
+ Autobuild.progress_done(self)
295
303
  end
296
304
 
297
305
  # Install the result in prefix
298
306
  def install
299
- Dir.chdir(srcdir) do
300
- Autobuild.post_install_handlers.each do |b|
301
- Autobuild.apply_post_install(self, b)
302
- end
303
- @post_install_blocks.each do |b|
304
- Autobuild.apply_post_install(self, b)
305
- end
307
+ Autobuild.post_install_handlers.each do |b|
308
+ Autobuild.apply_post_install(self, b)
306
309
  end
310
+ @post_install_blocks.each do |b|
311
+ Autobuild.apply_post_install(self, b)
312
+ end
313
+ # Safety net for forgotten progress_done
314
+ progress_done
315
+
307
316
  Autobuild.touch_stamp(installstamp)
308
317
  update_environment
309
318
  end
@@ -533,6 +542,18 @@ module Autobuild
533
542
  @parallel_build_level
534
543
  end
535
544
  end
545
+
546
+ def working_directory
547
+ @in_dir_stack.last
548
+ end
549
+
550
+ def in_dir(directory)
551
+ @in_dir_stack << directory
552
+ yield
553
+
554
+ ensure
555
+ @in_dir_stack.pop
556
+ end
536
557
  end
537
558
 
538
559
  def self.package_set(spec)
@@ -40,9 +40,10 @@ module Autobuild
40
40
  def with_doc(target = 'doc')
41
41
  task "#{name}-doc" => configurestamp
42
42
  doc_task do
43
- Dir.chdir(builddir) do
44
- progress "generating documentation for %s"
45
- Subprocess.run(self, 'doc', Autobuild.tool(:make), "-j#{parallel_build_level}", target)
43
+ in_dir(builddir) do
44
+ progress_start "generating documentation for %s" do
45
+ Subprocess.run(self, 'doc', Autobuild.tool(:make), "-j#{parallel_build_level}", target)
46
+ end
46
47
  yield if block_given?
47
48
  end
48
49
  end
@@ -214,28 +215,29 @@ module Autobuild
214
215
 
215
216
  file conffile do
216
217
  isolate_errors do
217
- Dir.chdir(srcdir) do
218
+ in_dir(srcdir) do
218
219
  if using[:autogen].nil?
219
- using[:autogen] = %w{autogen autogen.sh}.find { |f| File.exists?(f) }
220
+ using[:autogen] = %w{autogen autogen.sh}.find { |f| File.exists?(File.join(srcdir, f)) }
220
221
  end
221
222
 
222
223
  autodetect_needed_stages
223
224
 
224
- progress "generating build system for %s"
225
- if using[:libtool]
226
- Subprocess.run(self, 'configure', Autobuild.tool('libtoolize'), '--copy')
227
- end
228
- if using[:autogen]
229
- Subprocess.run(self, 'configure', File.expand_path(using[:autogen]))
230
- else
231
- [ :aclocal, :autoconf, :autoheader, :automake ].each do |tool|
232
- if tool_flag = using[tool]
233
- tool_program = if tool_flag.respond_to?(:to_str)
234
- tool_flag.to_str
235
- else; Autobuild.tool(tool)
236
- end
237
-
238
- Subprocess.run(self, 'configure', tool_program)
225
+ progress_start "generating build system for %s" do
226
+ if using[:libtool]
227
+ Subprocess.run(self, 'configure', Autobuild.tool('libtoolize'), '--copy')
228
+ end
229
+ if using[:autogen]
230
+ Subprocess.run(self, 'configure', File.expand_path(using[:autogen]))
231
+ else
232
+ [ :aclocal, :autoconf, :autoheader, :automake ].each do |tool|
233
+ if tool_flag = using[tool]
234
+ tool_program = if tool_flag.respond_to?(:to_str)
235
+ tool_flag.to_str
236
+ else; Autobuild.tool(tool)
237
+ end
238
+
239
+ Subprocess.run(self, 'configure', tool_program)
240
+ end
239
241
  end
240
242
  end
241
243
  end
@@ -249,7 +251,7 @@ module Autobuild
249
251
  # Configure the builddir directory before starting make
250
252
  def configure
251
253
  super do
252
- Dir.chdir(builddir) do
254
+ in_dir(builddir) do
253
255
  command = [ "#{srcdir}/configure"]
254
256
  if force_config_status
255
257
  command << "--no-create"
@@ -257,29 +259,32 @@ module Autobuild
257
259
  command << "--prefix=#{prefix}"
258
260
  command += Array[*configureflags]
259
261
 
260
- progress "configuring build system for %s"
261
- Subprocess.run(self, 'configure', *command)
262
+ progress_start "configuring build system for %s" do
263
+ Subprocess.run(self, 'configure', *command)
264
+ end
262
265
  end
263
266
  end
264
267
  end
265
268
 
266
269
  # Do the build in builddir
267
270
  def build
268
- Dir.chdir(builddir) do
269
- progress "building %s [progress not available]"
270
- if force_config_status
271
- Subprocess.run(self, 'build', './config.status')
271
+ in_dir(builddir) do
272
+ progress_start "building %s [progress not available]" do
273
+ if force_config_status
274
+ Subprocess.run(self, 'build', './config.status')
275
+ end
276
+ Subprocess.run(self, 'build', Autobuild.tool(:make), "-j#{parallel_build_level}")
272
277
  end
273
- Subprocess.run(self, 'build', Autobuild.tool(:make), "-j#{parallel_build_level}")
274
278
  end
275
279
  Autobuild.touch_stamp(buildstamp)
276
280
  end
277
281
 
278
282
  # Install the result in prefix
279
283
  def install
280
- Dir.chdir(builddir) do
281
- progress "installing %s"
282
- Subprocess.run(self, 'install', Autobuild.tool(:make), "-j#{parallel_build_level}", 'install')
284
+ in_dir(builddir) do
285
+ progress_start "installing %s" do
286
+ Subprocess.run(self, 'install', Autobuild.tool(:make), 'install')
287
+ end
283
288
  end
284
289
 
285
290
  super
@@ -1,4 +1,5 @@
1
1
  require 'autobuild/configurable'
2
+ require 'autobuild/packages/gnumake'
2
3
 
3
4
  module Autobuild
4
5
  def self.cmake(options, &block)
@@ -202,14 +203,15 @@ module Autobuild
202
203
  # Declare that the given target can be used to generate documentation
203
204
  def with_doc(target = 'doc')
204
205
  doc_task do
205
- Dir.chdir(builddir) do
206
- progress "generating documentation for %s"
207
- if internal_doxygen_mode?
208
- run_doxygen
209
- else
210
- Subprocess.run(self, 'doc', Autobuild.tool(:make), "-j#{parallel_build_level}", target)
206
+ in_dir(builddir) do
207
+ progress_start "generating documentation for %s" do
208
+ if internal_doxygen_mode?
209
+ run_doxygen
210
+ else
211
+ Subprocess.run(self, 'doc', Autobuild.tool(:make), "-j#{parallel_build_level}", target)
212
+ end
213
+ yield if block_given?
211
214
  end
212
- yield if block_given?
213
215
  end
214
216
  end
215
217
  end
@@ -273,9 +275,9 @@ module Autobuild
273
275
  puts "option '#{name}' changed value: '#{old_value}' => '#{value}'"
274
276
  end
275
277
  if old_value
276
- progress "%s: changed value of #{name} from #{old_value} to #{value}"
278
+ message "%s: changed value of #{name} from #{old_value} to #{value}"
277
279
  else
278
- progress "%s: setting value of #{name} to #{value}"
280
+ message "%s: setting value of #{name} to #{value}"
279
281
  end
280
282
 
281
283
  true
@@ -295,7 +297,7 @@ module Autobuild
295
297
  # Configure the builddir directory before starting make
296
298
  def configure
297
299
  super do
298
- Dir.chdir(builddir) do
300
+ in_dir(builddir) do
299
301
  if !File.file?(File.join(srcdir, 'CMakeLists.txt'))
300
302
  raise ConfigException, "#{srcdir} contains no CMakeLists.txt file"
301
303
  end
@@ -310,25 +312,28 @@ module Autobuild
310
312
  end
311
313
  command << srcdir
312
314
 
313
- progress "configuring CMake build system for %s"
314
- if full_reconfigures?
315
- FileUtils.rm_f cmake_cache
315
+ progress_start "configuring CMake build system for %s" do
316
+ if full_reconfigures?
317
+ FileUtils.rm_f cmake_cache
318
+ end
319
+ Subprocess.run(self, 'configure', *command)
316
320
  end
317
- Subprocess.run(self, 'configure', *command)
318
321
  end
319
322
  end
320
323
  end
321
324
 
322
325
  # Do the build in builddir
323
326
  def build
324
- Dir.chdir(builddir) do
325
- progress_with_value "building %s"
326
- if always_reconfigure || !File.file?('Makefile')
327
- Subprocess.run(self, 'build', Autobuild.tool(:cmake), '.')
328
- end
329
- Subprocess.run(self, 'build', Autobuild.tool(:make), "-j#{parallel_build_level}") do |line|
330
- if line =~ /\[\s+(\d+)%\]/
331
- progress_value Integer($1)
327
+ in_dir(builddir) do
328
+ progress_start "building %s", :done_message => "building %s (100%%)" do
329
+ if always_reconfigure || !File.file?('Makefile')
330
+ Subprocess.run(self, 'build', Autobuild.tool(:cmake), '.')
331
+ end
332
+
333
+ Autobuild.make_subcommand(self, 'build') do |line|
334
+ if line =~ /\[\s+(\d+)%\]/
335
+ progress "building %s (#{Integer($1)}%%)"
336
+ end
332
337
  end
333
338
  end
334
339
  end
@@ -337,9 +342,10 @@ module Autobuild
337
342
 
338
343
  # Install the result in prefix
339
344
  def install
340
- Dir.chdir(builddir) do
341
- progress "installing %s"
342
- Subprocess.run(self, 'install', Autobuild.tool(:make), "-j#{parallel_build_level}", 'install')
345
+ in_dir(builddir) do
346
+ progress_start "installing %s" do
347
+ Subprocess.run(self, 'install', Autobuild.tool(:make), "-j#{parallel_build_level}", 'install')
348
+ end
343
349
  end
344
350
  super
345
351
  end
@@ -132,9 +132,10 @@ module Autobuild
132
132
  file genomstamp => genom_dependencies
133
133
  file genomstamp => srcdir do
134
134
  isolate_errors do
135
- Dir.chdir(srcdir) do
136
- progress "generating GenoM files for %s"
137
- Subprocess.run(self, 'genom', *cmdline)
135
+ in_dir(srcdir) do
136
+ progress_start "generating GenoM files for %s" do
137
+ Subprocess.run(self, 'genom', *cmdline)
138
+ end
138
139
  end
139
140
  end
140
141
  end
@@ -145,8 +146,9 @@ module Autobuild
145
146
  # configure does not depend on the .gen file
146
147
  # since the generation takes care of rebuilding configure
147
148
  # if .gen has changed
148
- progress "generating build system for %s"
149
- Dir.chdir(srcdir) { Subprocess.run(self, 'genom', File.expand_path('autogen')) }
149
+ progress_start "generating build system for %s" do
150
+ in_dir(srcdir) { Subprocess.run(self, 'genom', File.expand_path('autogen')) }
151
+ end
150
152
  end
151
153
  end
152
154
 
@@ -70,7 +70,7 @@ module Autobuild
70
70
  end
71
71
  @orogen_options = []
72
72
  @default_type_export_policy = :used
73
- @transports = %w{corba typelib}
73
+ @transports = %w{corba typelib mqueue}
74
74
  @rtt_scripting = true
75
75
 
76
76
  attr_reader :orogen_options
@@ -333,15 +333,16 @@ module Autobuild
333
333
  needs_regen ||= (Rake::Task[Orogen.orogen_root].timestamp > Rake::Task[genstamp].timestamp)
334
334
 
335
335
  if needs_regen
336
- progress "generating oroGen project %s"
337
- Dir.chdir(srcdir) do
338
- Subprocess.run self, 'orogen', guess_ruby_name, self.class.orogen_bin, *cmdline
339
- File.open(genstamp, 'w') do |io|
340
- io.print cmdline.join("\n")
336
+ progress_start "generating oroGen project %s" do
337
+ in_dir(srcdir) do
338
+ Subprocess.run self, 'orogen', guess_ruby_name, self.class.orogen_bin, *cmdline
339
+ File.open(genstamp, 'w') do |io|
340
+ io.print cmdline.join("\n")
341
+ end
341
342
  end
342
343
  end
343
344
  else
344
- progress "no need to regenerate the oroGen project %s"
345
+ message "no need to regenerate the oroGen project %s"
345
346
  Autobuild.touch_stamp genstamp
346
347
  end
347
348
  end
@@ -350,9 +351,7 @@ module Autobuild
350
351
  if !File.file?(genstamp)
351
352
  true
352
353
  elsif File.file?(File.join(builddir, 'Makefile'))
353
- Dir.chdir(builddir) do
354
- system("#{Autobuild.tool('make')} check-uptodate > /dev/null 2>&1")
355
- end
354
+ system("#{Autobuild.tool('make')} -C #{builddir} check-uptodate > /dev/null 2>&1")
356
355
  else
357
356
  true
358
357
  end
@@ -15,30 +15,81 @@ require 'autobuild/config'
15
15
  require 'autobuild/exceptions'
16
16
 
17
17
  module Autobuild
18
- def self.progress(*args)
19
- if @last_msg
20
- progress_value(100)
18
+ def self.message(*args)
19
+ if !progress_messages.empty?
21
20
  puts
22
21
  end
23
- @last_msg = nil
24
-
25
22
  if args.empty?
26
23
  puts
27
24
  else
28
- puts " #{color(*args)}"
25
+ puts "#{color(*args)}"
29
26
  end
27
+ @last_msg = nil
30
28
  end
31
- def self.progress_with_value(*args)
32
- if @last_msg
33
- progress_value(100)
34
- puts
29
+
30
+ class << self
31
+ attr_reader :progress_messages
32
+ end
33
+ @progress_messages = Array.new
34
+
35
+ def self.progress_start(key, *args)
36
+ if args.last.kind_of?(Hash)
37
+ options = Kernel.validate_options args.pop, :done_message => nil
38
+ else
39
+ options = Hash.new
35
40
  end
36
- @last_msg = " #{color(args[0], *args[1..-1])}"
37
41
 
38
- print @last_msg
42
+ progress_done(key)
43
+ progress_messages << [key, color(*args)]
44
+ display_progress
45
+
46
+ if block_given?
47
+ begin
48
+ yield
49
+ if options[:done_message]
50
+ progress(key, *options[:done_message])
51
+ end
52
+ ensure
53
+ progress_done(key)
54
+ end
55
+ end
39
56
  end
40
- def self.progress_value(value)
41
- print "\r#{@last_msg} (#{value}%)"
57
+ def self.progress(key, *args)
58
+ found = false
59
+ progress_messages.map! do |msg_key, msg|
60
+ if msg_key == key
61
+ found = true
62
+ [msg_key, color(*args)]
63
+ else
64
+ [msg_key, msg]
65
+ end
66
+ end
67
+ if !found
68
+ progress_messages << [key, color(*args)]
69
+ end
70
+ display_progress
71
+ end
72
+ def self.progress_done(key)
73
+ found = false
74
+ progress_messages.delete_if do |msg_key, msg|
75
+ if msg_key == key
76
+ found = true
77
+ end
78
+ end
79
+ if found
80
+ puts
81
+ display_progress
82
+ end
83
+ found
84
+ end
85
+
86
+ def self.display_progress
87
+ msg = "#{progress_messages.map(&:last).join(" | ")}"
88
+ if @last_msg && @last_msg.length > msg.length
89
+ print "\r" + " " * @last_msg.length
90
+ end
91
+ print "\r #{msg}"
92
+ @last_msg = msg
42
93
  end
43
94
 
44
95
  # The exception type that is used to report multiple errors that occured
@@ -133,8 +133,11 @@ module Autobuild::Subprocess
133
133
  STDOUT.sync = true
134
134
 
135
135
  input_streams = []
136
+ options = Hash.new
136
137
  if command.last.kind_of?(Hash)
137
138
  options = command.pop
139
+ options = Kernel.validate_options options,
140
+ :input => nil, :working_directory => nil
138
141
  if options[:input]
139
142
  input_streams = [options[:input]]
140
143
  end
@@ -155,6 +158,10 @@ module Autobuild::Subprocess
155
158
  else Autobuild.logdir
156
159
  end
157
160
 
161
+ if target.respond_to?(:working_directory)
162
+ options[:working_directory] ||= target.working_directory
163
+ end
164
+
158
165
  logname = File.join(logdir, "#{target_name}-#{phase}.log")
159
166
  if !File.directory?(File.dirname(logname))
160
167
  FileUtils.mkdir_p File.dirname(logname)
@@ -201,6 +208,10 @@ module Autobuild::Subprocess
201
208
  cwrite.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
202
209
 
203
210
  pid = fork do
211
+ if options[:working_directory]
212
+ Dir.chdir(options[:working_directory])
213
+ end
214
+ logfile.puts "in directory #{Dir.pwd}"
204
215
  begin
205
216
  cwrite.sync = true
206
217
  if Autobuild.nice
@@ -1,5 +1,5 @@
1
1
  module Autobuild
2
- VERSION = "1.5.61" unless defined? Autobuild::VERSION
2
+ VERSION = "1.6.0.b1" unless defined? Autobuild::VERSION
3
3
  end
4
4
 
5
5
 
metadata CHANGED
@@ -1,13 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: autobuild
3
3
  version: !ruby/object:Gem::Version
4
- hash: 121
5
- prerelease:
4
+ hash: 53
5
+ prerelease: 6
6
6
  segments:
7
7
  - 1
8
- - 5
9
- - 61
10
- version: 1.5.61
8
+ - 6
9
+ - 0
10
+ - b
11
+ - 1
12
+ version: 1.6.0.b1
11
13
  platform: ruby
12
14
  authors:
13
15
  - Sylvain Joyeux
@@ -15,7 +17,7 @@ autorequire:
15
17
  bindir: bin
16
18
  cert_chain: []
17
19
 
18
- date: 2012-02-15 00:00:00 Z
20
+ date: 2012-03-08 00:00:00 Z
19
21
  dependencies:
20
22
  - !ruby/object:Gem::Dependency
21
23
  name: rake
@@ -155,12 +157,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
155
157
  required_rubygems_version: !ruby/object:Gem::Requirement
156
158
  none: false
157
159
  requirements:
158
- - - ">="
160
+ - - ">"
159
161
  - !ruby/object:Gem::Version
160
- hash: 3
162
+ hash: 25
161
163
  segments:
162
- - 0
163
- version: "0"
164
+ - 1
165
+ - 3
166
+ - 1
167
+ version: 1.3.1
164
168
  requirements: []
165
169
 
166
170
  rubyforge_project: autobuild