autobuild 1.17.0 → 1.18.0

Sign up to get free protection for your applications and to get access to all the features.
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
-