autobuild 1.17.0 → 1.18.0

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +107 -0
  3. data/Gemfile +2 -1
  4. data/Rakefile +1 -4
  5. data/autobuild.gemspec +14 -11
  6. data/bin/autobuild +4 -3
  7. data/lib/autobuild.rb +4 -5
  8. data/lib/autobuild/build_logfile.rb +6 -4
  9. data/lib/autobuild/config.rb +90 -40
  10. data/lib/autobuild/configurable.rb +30 -18
  11. data/lib/autobuild/environment.rb +126 -120
  12. data/lib/autobuild/exceptions.rb +48 -31
  13. data/lib/autobuild/import/archive.rb +134 -82
  14. data/lib/autobuild/import/cvs.rb +28 -24
  15. data/lib/autobuild/import/darcs.rb +13 -16
  16. data/lib/autobuild/import/git-lfs.rb +37 -30
  17. data/lib/autobuild/import/git.rb +231 -179
  18. data/lib/autobuild/import/hg.rb +23 -18
  19. data/lib/autobuild/import/svn.rb +48 -29
  20. data/lib/autobuild/importer.rb +530 -499
  21. data/lib/autobuild/mail_reporter.rb +77 -77
  22. data/lib/autobuild/package.rb +171 -101
  23. data/lib/autobuild/packages/autotools.rb +47 -42
  24. data/lib/autobuild/packages/cmake.rb +71 -65
  25. data/lib/autobuild/packages/dummy.rb +9 -8
  26. data/lib/autobuild/packages/genom.rb +1 -1
  27. data/lib/autobuild/packages/gnumake.rb +19 -13
  28. data/lib/autobuild/packages/import.rb +2 -6
  29. data/lib/autobuild/packages/orogen.rb +32 -31
  30. data/lib/autobuild/packages/pkgconfig.rb +2 -2
  31. data/lib/autobuild/packages/python.rb +7 -2
  32. data/lib/autobuild/packages/ruby.rb +22 -17
  33. data/lib/autobuild/parallel.rb +35 -39
  34. data/lib/autobuild/pkgconfig.rb +25 -13
  35. data/lib/autobuild/progress_display.rb +23 -23
  36. data/lib/autobuild/rake_task_extension.rb +6 -6
  37. data/lib/autobuild/reporting.rb +38 -26
  38. data/lib/autobuild/subcommand.rb +72 -65
  39. data/lib/autobuild/test.rb +8 -7
  40. data/lib/autobuild/test_utility.rb +10 -9
  41. data/lib/autobuild/timestamps.rb +28 -23
  42. data/lib/autobuild/tools.rb +17 -16
  43. data/lib/autobuild/utility.rb +16 -18
  44. data/lib/autobuild/version.rb +1 -1
  45. metadata +39 -38
@@ -8,100 +8,100 @@
8
8
 
9
9
  ## Report by mail
10
10
  if Autobuild::HAS_RMAIL
11
- module Autobuild
12
- class MailReporter < Reporter
13
- def default_mail
14
- Etc::endpwent
15
- uname = while (pwent = Etc::getpwent)
16
- break (pwent.name) if pwent.uid == Process.uid
17
- end
11
+ module Autobuild
12
+ class MailReporter < Reporter
13
+ def default_mail
14
+ Etc.endpwent
15
+ uname = while (pwent = Etc.getpwent)
16
+ break pwent.name if pwent.uid == Process.uid
17
+ end
18
18
 
19
- raise "FATAL: cannot find a user with uid=#{Process.uid}" unless uname
20
- "#{pwent.name}@#{Socket.gethostname}"
21
- end
22
-
23
- attr_reader :from_email, :to_email, :smtp_hostname, :smtp_port, :subject, :only_errors
24
- def initialize(config)
25
- @from_email = (config[:from] || default_mail)
26
- @to_email = (config[:to] || default_mail)
27
- @subject = (config[:subject] || "Build %result% on #{Socket.gethostname} at %time%")
28
- @only_errors = config[:only_errors]
29
- @smtp_hostname = (config[:smtp] || "localhost" )
30
- @smtp_port = Integer(config[:port] || Socket.getservbyname('smtp'))
31
- end
19
+ raise "FATAL: cannot find a user with uid=#{Process.uid}" unless uname
32
20
 
33
- def error(error)
34
- if error.mail?
35
- send_mail("failed", error.to_s)
21
+ "#{pwent.name}@#{Socket.gethostname}"
36
22
  end
37
- end
38
23
 
39
- def success
40
- unless only_errors
41
- send_mail("success", Autobuild.post_success_message || "")
24
+ attr_reader :from_email, :to_email, :smtp_hostname, :smtp_port,
25
+ :subject, :only_errors
26
+ def initialize(config)
27
+ @from_email = (config[:from] || default_mail)
28
+ @to_email = (config[:to] || default_mail)
29
+ @subject =
30
+ config[:subject] ||
31
+ "Build %result% on #{Socket.gethostname} at %time%"
32
+ @only_errors = config[:only_errors]
33
+ @smtp_hostname = (config[:smtp] || "localhost")
34
+ @smtp_port = Integer(config[:port] || Socket.getservbyname('smtp'))
42
35
  end
43
- end
44
36
 
45
- def send_mail(result, body = "")
46
- mail = RMail::Message.new
47
- mail.header.date = Time.now
48
- mail.header.from = from_email
49
- mail.header.subject = subject.
50
- gsub('%result%', result).
51
- gsub('%time%', Time.now.to_s).
52
- gsub('%hostname%', Socket.gethostname)
53
-
54
- part = RMail::Message.new
55
- part.header.set('Content-Type', 'text/plain')
56
- part.body = body
57
- mail.add_part(part)
37
+ def error(error)
38
+ send_mail("failed", error.to_s) if error.mail?
39
+ end
58
40
 
59
- # Attach log files
60
- Reporting.each_log do |file|
61
- name = file[Autobuild.logdir.size..-1]
62
- mail.add_file(name, file)
41
+ def success
42
+ unless only_errors
43
+ send_mail("success", Autobuild.post_success_message || "")
44
+ end
63
45
  end
64
46
 
65
- # Send the mails
66
- if smtp_hostname =~ /\// && File.directory?(File.dirname(smtp_hostname))
67
- File.open(smtp_hostname, 'w') do |io|
68
- io.puts "From: #{from_email}"
69
- io.puts "To: #{to_email.join(" ")}"
70
- io.write RMail::Serialize.write('', mail)
47
+ def send_mail(result, body = "")
48
+ mail = RMail::Message.new
49
+ mail.header.date = Time.now
50
+ mail.header.from = from_email
51
+ mail.header.subject = subject.
52
+ gsub('%result%', result).
53
+ gsub('%time%', Time.now.to_s).
54
+ gsub('%hostname%', Socket.gethostname)
55
+
56
+ part = RMail::Message.new
57
+ part.header.set('Content-Type', 'text/plain')
58
+ part.body = body
59
+ mail.add_part(part)
60
+
61
+ # Attach log files
62
+ Reporting.each_log do |file|
63
+ name = file[Autobuild.logdir.size..-1]
64
+ mail.add_file(name, file)
71
65
  end
72
- puts "saved notification email in #{smtp_hostname}"
73
- else
74
- smtp = Net::SMTP.new(smtp_hostname, smtp_port)
75
- smtp.start {
76
- to_email.each do |email|
77
- mail.header.to = email
78
- smtp.send_mail RMail::Serialize.write('', mail), from_email, email
66
+
67
+ # Send the mails
68
+ if smtp_hostname =~ %r{/} && File.directory?(File.dirname(smtp_hostname))
69
+ File.open(smtp_hostname, 'w') do |io|
70
+ io.puts "From: #{from_email}"
71
+ io.puts "To: #{to_email.join(' ')}"
72
+ io.write RMail::Serialize.write('', mail)
73
+ end
74
+ puts "saved notification email in #{smtp_hostname}"
75
+ else
76
+ smtp = Net::SMTP.new(smtp_hostname, smtp_port)
77
+ smtp.start do
78
+ to_email.each do |email|
79
+ mail.header.to = email
80
+ smtp.send_mail(RMail::Serialize.write('', mail),
81
+ from_email, email)
82
+ end
79
83
  end
80
- }
81
84
 
82
- # Notify the sending
83
- puts "sent notification mail to #{to_email} with source #{from_email}"
85
+ # Notify the sending
86
+ puts "sent notification mail to #{to_email} with source #{from_email}"
87
+ end
84
88
  end
85
89
  end
86
90
  end
87
- end
88
91
 
89
- module RMail
90
- class Message
91
- ## Attachs a file to a message
92
- def add_file(name, path, content_type='text/plain')
93
- part = RMail::Message.new
94
- part.header.set('Content-Type', content_type)
95
- part.header.set('Content-Disposition', 'attachment', 'filename' => name)
96
- part.body = ''
97
- File.open(path) do |file|
98
- part.body << file.readlines.join("")
92
+ module RMail
93
+ class Message
94
+ ## Attachs a file to a message
95
+ def add_file(name, path, content_type = 'text/plain')
96
+ part = RMail::Message.new
97
+ part.header.set('Content-Type', content_type)
98
+ part.header.set('Content-Disposition', 'attachment', 'filename' => name)
99
+ part.body = ''
100
+ File.open(path) do |file|
101
+ part.body << file.readlines.join("")
102
+ end
103
+ add_part(part)
99
104
  end
100
- self.add_part(part)
101
105
  end
102
106
  end
103
107
  end
104
- end # if Autobuild::HAS_RMAIL
105
-
106
-
107
-
@@ -1,10 +1,10 @@
1
1
  module Autobuild
2
- TARGETS = %w{import prepare build}
2
+ TARGETS = %w[import prepare build].freeze
3
3
 
4
4
  class << self
5
5
  attr_accessor :ignore_errors
6
6
  end
7
-
7
+
8
8
  # Basic block for the autobuilder
9
9
  #
10
10
  # The build is done in three phases:
@@ -43,14 +43,18 @@ class Package
43
43
  # The set of utilities attached to this package
44
44
  # @return [{String=>Utility}]
45
45
  attr_reader :utilities
46
+
46
47
  # Whether {#apply_post_install} has been called
47
- def applied_post_install?; !!@applied_post_install end
48
-
48
+ def applied_post_install?
49
+ @applied_post_install
50
+ end
51
+
49
52
  # Sets importer object for this package. Defined for backwards compatibility.
50
53
  # Use the #importer attribute instead
51
54
  def import=(value)
52
55
  @importer = value
53
56
  end
57
+
54
58
  # Sets an importer object for this package
55
59
  attr_accessor :importer
56
60
 
@@ -74,11 +78,20 @@ def add_stat(phase, duration)
74
78
  end
75
79
 
76
80
  # Absolute path to the source directory. See #srcdir=
77
- def srcdir; File.expand_path(@srcdir || name, Autobuild.srcdir) end
81
+ def srcdir
82
+ File.expand_path(@srcdir || name, Autobuild.srcdir)
83
+ end
84
+
78
85
  # Absolute path to the import directory. See #importdir=
79
- def importdir; File.expand_path(@importdir || srcdir, Autobuild.srcdir) end
86
+ def importdir
87
+ File.expand_path(@importdir || srcdir, Autobuild.srcdir)
88
+ end
89
+
80
90
  # Absolute path to the installation directory. See #prefix=
81
- def prefix; File.expand_path(@prefix || '', Autobuild.prefix) end
91
+ def prefix
92
+ File.expand_path(@prefix || '', Autobuild.prefix)
93
+ end
94
+
82
95
  # Absolute path to the log directory for this package. See #logdir=
83
96
  def logdir
84
97
  if @logdir
@@ -115,17 +128,19 @@ def update?
115
128
  # Returns true if this package has already been updated. It will not be
116
129
  # true if the importer has been called while Autobuild.do_update was
117
130
  # false.
118
- def updated?; !!@updated end
131
+ def updated?
132
+ @updated
133
+ end
119
134
 
120
135
  def initialize(spec = Hash.new)
121
136
  @srcdir = @importdir = @logdir = @prefix = nil
122
137
  @updated = false
123
138
  @update = nil
124
139
  @failed = nil
125
- @dependencies = Array.new
126
- @provides = Array.new
140
+ @dependencies = Array.new
141
+ @provides = Array.new
142
+ @statistics = Hash.new
127
143
  @parallel_build_level = nil
128
- @statistics = Hash.new
129
144
  @failures = Array.new
130
145
  @post_install_blocks = Array.new
131
146
  @applied_post_install = false
@@ -139,19 +154,23 @@ def initialize(spec = Hash.new)
139
154
  if Hash === spec
140
155
  name, depends = spec.to_a.first
141
156
  else
142
- name, depends = spec, nil
157
+ name = spec
158
+ depends = nil
143
159
  end
144
160
 
145
161
  name = name.to_s
146
162
  @name = name
147
- raise ConfigException, "package #{name} is already defined" if Autobuild::Package[name]
163
+ if Autobuild::Package[name]
164
+ raise ConfigException, "package #{name} is already defined"
165
+ end
166
+
148
167
  @@packages[name] = self
149
168
 
150
169
  # Call the config block (if any)
151
170
  yield(self) if block_given?
152
171
 
153
- self.doc_utility.source_dir ||= 'doc'
154
- self.doc_utility.target_dir ||= name
172
+ doc_utility.source_dir ||= 'doc'
173
+ doc_utility.target_dir ||= name
155
174
 
156
175
  # Define the default tasks
157
176
  task "#{name}-import" do
@@ -174,12 +193,10 @@ def initialize(spec = Hash.new)
174
193
  Rake::Task["#{name}-import"].invoke
175
194
  Rake::Task["#{name}-prepare"].invoke
176
195
  Rake::Task["#{name}-build"].invoke
177
- if has_doc? && Autobuild.do_doc
178
- Rake::Task["#{name}-doc"].invoke
179
- end
196
+ Rake::Task["#{name}-doc"].invoke if has_doc? && Autobuild.do_doc
180
197
  end
181
198
  task :default => name
182
-
199
+
183
200
  # The dependencies will be declared in the import phase, so save
184
201
  # them there for now
185
202
  @spec_dependencies = depends
@@ -217,7 +234,10 @@ def built?
217
234
  def to_s
218
235
  "#<#{self.class} name=#{name}>"
219
236
  end
220
- def inspect; to_s end
237
+
238
+ def inspect
239
+ to_s
240
+ end
221
241
 
222
242
  # @api private
223
243
  #
@@ -226,8 +246,8 @@ def inspect; to_s end
226
246
  #
227
247
  # @param [EnvOp] op
228
248
  # @return [void]
229
- def add_env_op(op)
230
- env << op
249
+ def add_env_op(envop)
250
+ env << envop
231
251
  end
232
252
 
233
253
  # Add value(s) to a list-based environment variable
@@ -300,11 +320,15 @@ class IncompatibleEnvironment < ConfigException; end
300
320
  def apply_env(env, set = Hash.new, ops = Array.new)
301
321
  self.env.each do |env_op|
302
322
  next if ops.last == env_op
323
+
303
324
  if env_op.type == :set
304
- if last = set[env_op.name]
325
+ if (last = set[env_op.name])
305
326
  last_pkg, last_values = *last
306
327
  if last_values != env_op.values
307
- raise IncompatibleEnvironment, "trying to reset #{env_op.name} to #{env_op.values} in #{self.name} but this conflicts with #{last_pkg.name} already setting it to #{last_values}"
328
+ raise IncompatibleEnvironment, "trying to reset "\
329
+ "#{env_op.name} to #{env_op.values} in #{name} "\
330
+ "but this conflicts with #{last_pkg.name} "\
331
+ "already setting it to #{last_values}"
308
332
  end
309
333
  else
310
334
  set[env_op.name] = [self, env_op.values]
@@ -356,9 +380,7 @@ def resolved_env(root = Autobuild.env)
356
380
  # target files so that all the build phases of this package gets
357
381
  # retriggered. However, it should not clean the build products.
358
382
  def prepare_for_forced_build
359
- if File.exist?(installstamp)
360
- FileUtils.rm_f installstamp
361
- end
383
+ FileUtils.rm_f installstamp if File.exist?(installstamp)
362
384
  end
363
385
 
364
386
  # Called when the user asked for a full rebuild. It should delete the
@@ -366,9 +388,7 @@ def prepare_for_forced_build
366
388
  def prepare_for_rebuild
367
389
  prepare_for_forced_build
368
390
 
369
- if File.exist?(installstamp)
370
- FileUtils.rm_f installstamp
371
- end
391
+ FileUtils.rm_f installstamp if File.exist?(installstamp)
372
392
  end
373
393
 
374
394
  # Returns true if one of the operations applied on this package failed
@@ -388,18 +408,18 @@ def failed?
388
408
  # will subsequently be a noop. I.e. if +build+ fails, +install+ will do
389
409
  # nothing.
390
410
  def isolate_errors(options = Hash.new)
391
- if !options.kind_of?(Hash)
392
- options = Hash[mark_as_failed: true]
393
- end
411
+ options = Hash[mark_as_failed: true] unless options.kind_of?(Hash)
394
412
  options = validate_options options,
395
413
  mark_as_failed: true,
396
414
  ignore_errors: Autobuild.ignore_errors
397
415
 
398
416
  # Don't do anything if we already have failed
399
417
  if failed?
400
- if !options[:ignore_errors]
401
- raise AlreadyFailedError, "attempting to do an operation on a failed package"
418
+ unless options[:ignore_errors]
419
+ raise AlreadyFailedError, "attempting to do an operation "\
420
+ "on a failed package"
402
421
  end
422
+
403
423
  return
404
424
  end
405
425
 
@@ -413,18 +433,12 @@ def isolate_errors(options = Hash.new)
413
433
  raise
414
434
  rescue ::Exception => e
415
435
  @failures << e
416
- if options[:mark_as_failed]
417
- @failed = true
418
- end
436
+ @failed = true if options[:mark_as_failed]
419
437
 
420
438
  if options[:ignore_errors]
421
439
  lines = e.to_s.split("\n")
422
- if lines.empty?
423
- lines = e.message.split("\n")
424
- end
425
- if lines.empty?
426
- lines = ["unknown error"]
427
- end
440
+ lines = e.message.split("\n") if lines.empty?
441
+ lines = ["unknown error"] if lines.empty?
428
442
  message(lines.shift, :red, :bold)
429
443
  lines.each do |line|
430
444
  message(line)
@@ -434,9 +448,7 @@ def isolate_errors(options = Hash.new)
434
448
  raise
435
449
  end
436
450
  ensure
437
- if toplevel
438
- Thread.current[:isolate_errors] = false
439
- end
451
+ Thread.current[:isolate_errors] = false if toplevel
440
452
  end
441
453
  end
442
454
 
@@ -445,9 +457,7 @@ def isolate_errors(options = Hash.new)
445
457
  #
446
458
  # (see Importer#import)
447
459
  def import(options = Hash.new)
448
- if !options.respond_to?(:to_hash)
449
- options = Hash[only_local: options]
450
- end
460
+ options = Hash[only_local: options] unless options.respond_to?(:to_hash)
451
461
 
452
462
  if @importer
453
463
  result = @importer.import(self, options)
@@ -478,7 +488,8 @@ def prepare
478
488
  end
479
489
 
480
490
  def process_formatting_string(msg, *prefix_style)
481
- prefix, suffix = [], []
491
+ prefix = []
492
+ suffix = []
482
493
  msg.split(" ").each do |token|
483
494
  if token =~ /%s/
484
495
  suffix << token.gsub(/%s/, name)
@@ -492,7 +503,8 @@ def process_formatting_string(msg, *prefix_style)
492
503
  elsif prefix_style.empty?
493
504
  return (prefix + suffix).join(" ")
494
505
  else
495
- return [Autobuild.color(prefix.join(" "), *prefix_style), *suffix].join(" ")
506
+ colorized_prefix = Autobuild.color(prefix.join(" "), *prefix_style)
507
+ return [colorized_prefix, *suffix].join(" ")
496
508
  end
497
509
  end
498
510
 
@@ -511,17 +523,13 @@ def error(error_string)
511
523
  # Display a progress message. %s in the string is replaced by the
512
524
  # package name
513
525
  def message(*args)
514
- if !args.empty?
515
- args[0] = " #{process_formatting_string(args[0])}"
516
- end
526
+ args[0] = " #{process_formatting_string(args[0])}" unless args.empty?
517
527
  Autobuild.message(*args)
518
528
  end
519
529
 
520
530
  def progress_start(*args, done_message: nil, **raw_options, &block)
521
531
  args[0] = process_formatting_string(args[0], :bold)
522
- if done_message
523
- done_message = process_formatting_string(done_message)
524
- end
532
+ done_message = process_formatting_string(done_message) if done_message
525
533
  Autobuild.progress_start(self, *args,
526
534
  done_message: done_message, **raw_options, &block)
527
535
  end
@@ -559,13 +567,14 @@ def install
559
567
  end
560
568
 
561
569
  def run(*args, &block)
562
- if args.last.kind_of?(Hash)
563
- options = args.pop
564
- else
565
- options = Hash.new
566
- end
570
+ options =
571
+ if args.last.kind_of?(Hash)
572
+ args.pop
573
+ else
574
+ Hash.new
575
+ end
567
576
  options[:env] = options.delete(:resolved_env) ||
568
- (options[:env] || Hash.new).merge(resolved_env)
577
+ (options[:env] || Hash.new).merge(resolved_env)
569
578
  Autobuild::Subprocess.run(self, *args, options, &block)
570
579
  end
571
580
 
@@ -596,17 +605,49 @@ def task(*args, &block)
596
605
  task
597
606
  end
598
607
 
599
- def doc_dir=(value); doc_utility.source_dir = value end
600
- def doc_dir; doc_utility.source_dir end
601
- def doc_target_dir=(value); doc_utility.target_dir = value end
602
- def doc_target_dir; doc_utility.target_dir end
603
- def doc_task(&block); doc_utility.task(&block) end
604
- def generates_doc?; doc_utility.enabled? end
605
- def enable_doc; doc_utility.enabled = true end
606
- def disable_doc; doc_utility.enabled = false end
607
- def install_doc; doc_utility.install end
608
- def doc_disabled; doc_utility.disabled end
609
- def has_doc?; doc_utility.has_task? end
608
+ def doc_dir=(value)
609
+ doc_utility.source_dir = value
610
+ end
611
+
612
+ def doc_dir
613
+ doc_utility.source_dir
614
+ end
615
+
616
+ def doc_target_dir=(value)
617
+ doc_utility.target_dir = value
618
+ end
619
+
620
+ def doc_target_dir
621
+ doc_utility.target_dir
622
+ end
623
+
624
+ def doc_task(&block)
625
+ doc_utility.task(&block)
626
+ end
627
+
628
+ def generates_doc?
629
+ doc_utility.enabled?
630
+ end
631
+
632
+ def enable_doc
633
+ doc_utility.enabled = true
634
+ end
635
+
636
+ def disable_doc
637
+ doc_utility.enabled = false
638
+ end
639
+
640
+ def install_doc
641
+ doc_utility.install
642
+ end
643
+
644
+ def doc_disabled
645
+ doc_utility.disabled
646
+ end
647
+
648
+ def has_doc?
649
+ doc_utility.has_task?
650
+ end
610
651
 
611
652
  def post_install(*args, &block)
612
653
  if args.empty?
@@ -618,11 +659,35 @@ def post_install(*args, &block)
618
659
  end
619
660
  end
620
661
 
662
+ # Returns a unique hash representing a state of the package and
663
+ # its dependencies, if any dependency can't calculate its own
664
+ # fingerprint the result will be nil
665
+ # @return [String]
666
+ def fingerprint(recursive: true, memo: {})
667
+ self_fingerprint = importer.fingerprint(self)
668
+ return unless self_fingerprint
669
+
670
+ memo[name] = self_fingerprint
671
+ return self_fingerprint if !recursive || dependencies.empty?
672
+
673
+ dependency_fingerprints = dependencies.sort.map do |pkg_name|
674
+ pkg = Autobuild::Package[pkg_name]
675
+ unless (fingerprint = memo[pkg.name])
676
+ fingerprint = pkg.fingerprint(recursive: true, memo: memo)
677
+ return unless fingerprint
678
+ memo[pkg.name] = fingerprint
679
+ end
680
+ fingerprint
681
+ end
682
+
683
+ Digest::SHA1.hexdigest(self_fingerprint + dependency_fingerprints.join(""))
684
+ end
685
+
621
686
  # Returns the name of all the packages +self+ depends on
622
687
  def all_dependencies(result = Set.new)
623
688
  dependencies.each do |pkg_name|
624
689
  pkg = Autobuild::Package[pkg_name]
625
- if !result.include?(pkg.name)
690
+ unless result.include?(pkg.name)
626
691
  result << pkg.name
627
692
  pkg.all_dependencies(result)
628
693
  end
@@ -642,18 +707,21 @@ def depends_on?(package_name)
642
707
  def depends_on(*packages)
643
708
  packages.each do |p|
644
709
  p = p.name if p.respond_to?(:name)
645
- raise ArgumentError, "#{p.inspect} should be a string" if !p.respond_to? :to_str
710
+ unless p.respond_to?(:to_str)
711
+ raise ArgumentError, "#{p.inspect} should be a string"
712
+ end
713
+
646
714
  p = p.to_str
647
715
  next if p == name
648
- unless pkg = Package[p]
649
- raise ConfigException.new(self), "package #{p}, listed as a dependency of #{self.name}, is not defined"
716
+
717
+ unless (pkg = Package[p])
718
+ raise ConfigException.new(self), "package #{p}, "\
719
+ "listed as a dependency of #{name}, is not defined"
650
720
  end
651
721
 
652
722
  next if @dependencies.include?(pkg.name)
653
723
 
654
- if Autobuild.verbose
655
- Autobuild.message "#{name} depends on #{pkg.name}"
656
- end
724
+ Autobuild.message "#{name} depends on #{pkg.name}" if Autobuild.verbose
657
725
 
658
726
  task "#{name}-import" => "#{pkg.name}-import"
659
727
  task "#{name}-prepare" => "#{pkg.name}-prepare"
@@ -666,16 +734,17 @@ def depends_on(*packages)
666
734
  # listed in +packages+ are aliases for this package.
667
735
  def provides(*packages)
668
736
  packages.each do |p|
669
- raise ArgumentError, "#{p.inspect} should be a string" if !p.respond_to? :to_str
737
+ unless p.respond_to?(:to_str)
738
+ raise ArgumentError, "#{p.inspect} should be a string"
739
+ end
740
+
670
741
  p = p.to_str
671
742
  next if p == name
672
743
  next if @provides.include?(name)
673
744
 
674
- @@provides[p] = self
745
+ @@provides[p] = self
675
746
 
676
- if Autobuild.verbose
677
- Autobuild.message "#{name} provides #{p}"
678
- end
747
+ Autobuild.message "#{name} provides #{p}" if Autobuild.verbose
679
748
 
680
749
  task p => name
681
750
  task "#{p}-import" => "#{name}-import"
@@ -688,13 +757,11 @@ def provides(*packages)
688
757
  # Iterates on all available packages
689
758
  # if with_provides is true, includes the list
690
759
  # of package aliases
691
- def self.each(with_provides = false, &p)
692
- if !p
693
- return enum_for(:each, with_provides)
694
- end
760
+ def self.each(with_provides = false, &block)
761
+ return enum_for(:each, with_provides) unless block
695
762
 
696
- @@packages.each(&p)
697
- @@provides.each(&p) if with_provides
763
+ @@packages.each(&block)
764
+ @@provides.each(&block) if with_provides
698
765
  end
699
766
 
700
767
  # Gets a package from its name
@@ -719,7 +786,7 @@ def parallel_build_level=(value)
719
786
  end
720
787
 
721
788
  # Returns the level of parallelism authorized during the build for this
722
- # particular package. If not set, defaults to the system-wide option
789
+ # particular package. If not set, defaults to the system-wide option
723
790
  # (Autobuild.parallel_build_level and Autobuild.parallel_build_level=).
724
791
  #
725
792
  # The default value is the number of CPUs on this system.
@@ -740,7 +807,6 @@ def working_directory
740
807
  def in_dir(directory)
741
808
  @in_dir_stack << directory
742
809
  yield
743
-
744
810
  ensure
745
811
  @in_dir_stack.pop
746
812
  end
@@ -768,21 +834,26 @@ def disable(phases = Autobuild.all_phases)
768
834
  end
769
835
 
770
836
  def utility(utility_name)
771
- utilities[utility_name] ||= Autobuild.create_utility(utility_name, self)
837
+ utilities[utility_name.to_s] ||= Autobuild.create_utility(utility_name, self)
772
838
  end
773
839
 
840
+ def respond_to_missing?(name, _include_all)
841
+ utilities.key?(name.to_s)
842
+ end
774
843
 
775
- def method_missing(m, *args, &block)
776
- case m.to_s
844
+ def method_missing(name, *args, &block)
845
+ case name.to_s
777
846
  when /(\w+)_utility$/
778
847
  utility_name = $1
779
- if !args.empty?
848
+
849
+ unless args.empty?
780
850
  raise ArgumentError, "expected 0 arguments and got #{args.size}"
781
851
  end
852
+
782
853
  begin
783
854
  return utility(utility_name)
784
855
  rescue ArgumentError => e
785
- raise NoMethodError.new(m), e.message, e.backtrace
856
+ raise NoMethodError.new(name), e.message, e.backtrace
786
857
  end
787
858
  end
788
859
  super
@@ -797,4 +868,3 @@ def self.package_set(spec)
797
868
  end
798
869
  end
799
870
  end
800
-