autoproj 1.6.1 → 1.6.2.rc2

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.
@@ -32,9 +32,12 @@ module Autoproj
32
32
  def doc
33
33
  doc = (options[:doc] || "#{name} (no documentation for this option)")
34
34
  if doc.respond_to?(:to_ary) # multi-line
35
- first_line = Autoproj.color(doc[0, 1], :bold)
36
- remaining = doc[1..-1].join("\n").split("\n").join("\n ")
37
- first_line + "\n " + remaining
35
+ first_line = Autoproj.color(doc[0], :bold)
36
+ remaining = doc[1..-1]
37
+ if !remaining.empty?
38
+ remaining = remaining.join("\n").split("\n").join("\n ")
39
+ first_line + "\n " + remaining
40
+ end
38
41
  else
39
42
  doc
40
43
  end
@@ -80,6 +83,9 @@ module Autoproj
80
83
 
81
84
  def self.validate_string(value, options)
82
85
  if possible_values = options[:possible_values]
86
+ if options[:lowercase]
87
+ value = value.downcase
88
+ end
83
89
  if !possible_values.include?(value)
84
90
  raise InputError, "invalid value '#{value}', accepted values are '#{possible_values.join(", ")}'"
85
91
  end
@@ -97,6 +103,10 @@ module Autoproj
97
103
  end
98
104
  end
99
105
 
106
+ def self.reset_option(key)
107
+ @user_config.delete(key)
108
+ end
109
+
100
110
  def self.change_option(key, value, user_validated = false)
101
111
  @user_config[key] = [value, user_validated]
102
112
  end
@@ -20,6 +20,9 @@ module Autoproj
20
20
  end
21
21
  @aliases = Hash.new
22
22
 
23
+ attr_writer :silent
24
+ def silent?; @silent end
25
+
23
26
  def self.alias(old_name, new_name)
24
27
  @aliases[new_name] = old_name
25
28
  end
@@ -52,17 +55,24 @@ module Autoproj
52
55
  # The Gem::SpecFetcher object that should be used to query RubyGems, and
53
56
  # install RubyGems packages
54
57
  def gem_fetcher
55
- @gem_fetcher ||= Gem::SpecFetcher.fetcher
58
+ if !@gem_fetcher
59
+ Autobuild.progress "looking for RubyGems updates"
60
+ @gem_fetcher = Gem::SpecFetcher.fetcher
61
+ end
62
+ @gem_fetcher
56
63
  end
57
64
 
58
65
  def initialize(defs = Hash.new, file = nil)
59
66
  @definitions = defs.to_hash
60
67
  @sources = Hash.new
68
+ @installed_packages = Array.new
61
69
  if file
62
70
  defs.each_key do |package_name|
63
71
  sources[package_name] = file
64
72
  end
65
73
  end
74
+ @silent = true
75
+ @filter_uptodate_packages = true
66
76
  end
67
77
 
68
78
  # Returns the full path to the osdeps file from which the package
@@ -108,10 +118,15 @@ module Autoproj
108
118
  # Returns true if it is possible to install packages for the operating
109
119
  # system on which we are installed
110
120
  def self.supported_operating_system?
111
- osdef = operating_system
112
- return false if !osdef
113
-
114
- OS_PACKAGE_INSTALL.has_key?(osdef[0])
121
+ if @supported_operating_system.nil?
122
+ osdef = operating_system
123
+ @supported_operating_system =
124
+ if !osdef then false
125
+ else
126
+ OS_AUTO_PACKAGE_INSTALL.has_key?(osdef[0])
127
+ end
128
+ end
129
+ return @supported_operating_system
115
130
  end
116
131
 
117
132
  # Autodetects the operating system name and version
@@ -128,11 +143,14 @@ module Autoproj
128
143
  if @operating_system
129
144
  return @operating_system
130
145
  elsif Autoproj.has_config_key?('operating_system')
131
- @operating_system = Autoproj.user_config('operating_system')
132
- elsif data = os_from_lsb
146
+ return (@operating_system = Autoproj.user_config('operating_system'))
147
+ end
148
+
149
+ Autoproj.progress " autodetecting the operating system"
150
+ if data = os_from_lsb
133
151
  if data[0] != "debian"
134
- # Fall back to reading debian_version, as
135
- # sid is listed as lenny by lsb-release
152
+ # if on Debian proper, fall back to reading debian_version,
153
+ # as sid is listed as lenny by lsb-release
136
154
  @operating_system = data
137
155
  end
138
156
  end
@@ -180,15 +198,48 @@ module Autoproj
180
198
  return [distributor, [codename, version]]
181
199
  end
182
200
 
201
+ # On a dpkg-enabled system, checks if the provided package is installed
202
+ # and returns true if it is the case
203
+ def self.dpkg_package_installed?(package_name)
204
+ if !@dpkg_installed_packages
205
+ @dpkg_installed_packages = Set.new
206
+ dpkg_status = File.readlines('/var/lib/dpkg/status')
207
+ dpkg_status.grep(/^(Package|Status)/).
208
+ each_slice(2) do |package, status|
209
+ if status.chomp == "Status: install ok installed"
210
+ @dpkg_installed_packages << package.split[1].chomp
211
+ end
212
+ end
213
+ end
214
+
215
+ if package_name =~ /^(\w[a-z0-9+-.]+)/
216
+ @dpkg_installed_packages.include?($1)
217
+ else
218
+ Autoproj.progress "WARN: #{package_name} is not a valid Debian package name"
219
+ false
220
+ end
221
+ end
183
222
 
184
223
  GAIN_ROOT_ACCESS = <<-EOSCRIPT
185
- if test `id -u` != "0"; then
186
- exec sudo /bin/bash $0 "$@"
187
-
188
- fi
224
+ # Gain root access using sudo
225
+ if test `id -u` != "0"; then
226
+ exec sudo /bin/bash $0 "$@"
227
+
228
+ fi
189
229
  EOSCRIPT
190
230
 
191
- OS_PACKAGE_INSTALL = {
231
+ OS_PACKAGE_CHECK = {
232
+ 'debian' => method(:dpkg_package_installed?),
233
+ 'ubuntu' => method(:dpkg_package_installed?)
234
+ }
235
+ OS_USER_PACKAGE_INSTALL = {
236
+ 'debian' => "apt-get install '%s'",
237
+ 'ubuntu' => "apt-get install '%s'",
238
+ 'gentoo' => "emerge '%s'",
239
+ 'arch' => "pacman '%s'"
240
+ }
241
+
242
+ OS_AUTO_PACKAGE_INSTALL = {
192
243
  'debian' => "export DEBIAN_FRONTEND=noninteractive; apt-get install -y '%s'",
193
244
  'ubuntu' => "export DEBIAN_FRONTEND=noninteractive; apt-get install -y '%s'",
194
245
  'gentoo' => "emerge --noreplace '%s'",
@@ -200,7 +251,6 @@ module Autoproj
200
251
  WRONG_OS_VERSION = 2
201
252
  IGNORE = 3
202
253
  PACKAGES = 4
203
- SHELL_SNIPPET = 5
204
254
  UNKNOWN_OS = 7
205
255
  AVAILABLE = 10
206
256
 
@@ -222,9 +272,6 @@ module Autoproj
222
272
  # [PACKAGES, definition]::
223
273
  # +definition+ is an array of package names that this OS's package
224
274
  # manager can understand
225
- # [SHELL_SNIPPET, definition]::
226
- # +definition+ is a string which is a shell snippet that will install
227
- # the package
228
275
  def resolve_package(name)
229
276
  os_name, os_version = OSDependencies.operating_system
230
277
 
@@ -260,7 +307,7 @@ module Autoproj
260
307
  version_list.to_s.split(',').
261
308
  map(&:downcase).
262
309
  any? do |v|
263
- os_version.any? { |osv| Regexp.new(v) =~ osv }
310
+ os_version.any? { |osv| Regexp.new(v) =~ osv }
264
311
  end
265
312
  end
266
313
 
@@ -275,7 +322,7 @@ module Autoproj
275
322
  elsif data.to_str =~ /\w+/
276
323
  return [PACKAGES, [data.to_str]]
277
324
  else
278
- return [SHELL_SNIPPET, data.to_str]
325
+ raise ConfigError, "invalid package specificiation #{data} in #{source_of(name)}"
279
326
  end
280
327
  end
281
328
 
@@ -287,7 +334,6 @@ module Autoproj
287
334
  os_name, os_version = OSDependencies.operating_system
288
335
 
289
336
  os_packages = []
290
- shell_snippets = []
291
337
  dependencies.each do |name|
292
338
  result = resolve_package(name)
293
339
  if result == NO_PACKAGE
@@ -295,32 +341,30 @@ module Autoproj
295
341
  elsif result == WRONG_OS
296
342
  raise ConfigError, "there is an osdeps definition for #{name}, but not for this operating system"
297
343
  elsif result == WRONG_OS_VERSION
298
- raise ConfigError, "there is an osdeps definition for #{name}, but no for this particular operating system version"
344
+ raise ConfigError, "there is an osdeps definition for #{name}, but not for this particular operating system version"
299
345
  elsif result == IGNORE
300
346
  next
301
347
  elsif result[0] == PACKAGES
302
348
  os_packages.concat(result[1])
303
- elsif result[0] == SHELL_SNIPPET
304
- shell_snippets << result[1]
305
349
  end
306
350
  end
307
351
 
308
- if !OS_PACKAGE_INSTALL.has_key?(os_name)
352
+ if !OS_AUTO_PACKAGE_INSTALL.has_key?(os_name)
309
353
  raise ConfigError, "I don't know how to install packages on #{os_name}"
310
354
  end
311
355
 
312
- return os_packages, shell_snippets
356
+ return os_packages
313
357
  end
314
358
 
315
359
 
316
- def generate_os_script(dependencies)
317
- os_name, os_version = OSDependencies.operating_system
318
- os_packages, shell_snippets = resolve_os_dependencies(dependencies)
319
-
320
- "#! /bin/bash\n" +
321
- GAIN_ROOT_ACCESS + "\n" +
322
- (OS_PACKAGE_INSTALL[os_name] % [os_packages.join("' '")]) +
323
- "\n" + shell_snippets.join("\n")
360
+ def generate_user_os_script(os_name, os_packages)
361
+ if OS_USER_PACKAGE_INSTALL[os_name]
362
+ (OS_USER_PACKAGE_INSTALL[os_name] % [os_packages.join("' '")])
363
+ else generate_auto_os_script(os_name, os_packages)
364
+ end
365
+ end
366
+ def generate_auto_os_script(os_name, os_packages)
367
+ (OS_AUTO_PACKAGE_INSTALL[os_name] % [os_packages.join("' '")])
324
368
  end
325
369
 
326
370
  # Returns true if +name+ is an acceptable OS package for this OS and
@@ -411,9 +455,25 @@ module Autoproj
411
455
  end
412
456
  end
413
457
 
414
- def filter_uptodate_gems(gems)
415
- Autobuild.progress "looking for RubyGems updates"
458
+ # Returns true if the osdeps system knows how to remove uptodate
459
+ # packages from the needs-to-be-installed package list on this OS
460
+ def can_filter_uptodate_packages?
461
+ os_name, _ = OSDependencies.operating_system
462
+ !!OS_PACKAGE_CHECK[os_name]
463
+ end
464
+
465
+ # Returns the set of packages in +packages+ that are not already
466
+ # installed on this OS, if it is supported
467
+ def filter_uptodate_os_packages(packages, os_name)
468
+ check_method = OS_PACKAGE_CHECK[os_name]
469
+ return packages.dup if !check_method
416
470
 
471
+ packages.find_all { |pkg| !check_method[pkg] }
472
+ end
473
+
474
+ # Returns the set of RubyGem packages in +packages+ that are not already
475
+ # installed, or that can be upgraded
476
+ def filter_uptodate_gems(gems)
417
477
  # Don't install gems that are already there ...
418
478
  gems = gems.dup
419
479
  gems.delete_if do |name|
@@ -434,143 +494,300 @@ module Autoproj
434
494
  gems
435
495
  end
436
496
 
437
- AUTOMATIC = true
438
- MANUAL = false
439
- WAIT = :wait
440
- ASK = :ask
497
+ HANDLE_ALL = 'all'
498
+ HANDLE_RUBY = 'ruby'
499
+ HANDLE_OS = 'os'
500
+ HANDLE_NONE = 'none'
501
+
502
+ def self.osdeps_mode_option_unsupported_os
503
+ long_doc =<<-EOT
504
+ The software packages that autoproj will have to build may require other
505
+ prepackaged softwares (a.k.a. OS dependencies) to be installed (RubyGems
506
+ packages, packages from your operating system/distribution, ...). Autoproj is
507
+ usually able to install those automatically, but unfortunately your operating
508
+ system is not (yet) supported by autoproj's osdeps mechanism, it can only offer
509
+ you some limited support.
510
+
511
+ RubyGem packages are a cross-platform mechanism, and are therefore supported.
512
+ However, you will have to install the kind of OS dependencies (so-called OS
513
+ packages)
514
+
515
+ This option is meant to allow you to control autoproj's behaviour while handling
516
+ OS dependencies.
517
+
518
+ * if you say "ruby", the RubyGem packages will be installed.
519
+ * if you say "none", autoproj will not do anything related to the OS
520
+ dependencies.
521
+
522
+ As any configuration value, the mode can be changed anytime by calling
523
+ an autoproj operation with the --reconfigure option (e.g. autoproj update
524
+ --reconfigure).
525
+
526
+ Finally, OS dependencies can be installed by calling "autoproj osdeps"
527
+ with the corresponding option (--all, --ruby, --os or --none). Calling
528
+ "autoproj osdeps" without arguments will also give you information as
529
+ to what you should install to compile the software successfully.
530
+ EOT
531
+ message = [ "Which prepackaged software (a.k.a. 'osdeps') should autoproj install automatically (ruby, none) ?", long_doc.strip ]
532
+
533
+ Autoproj.configuration_option 'osdeps_mode', 'string',
534
+ :default => 'ruby',
535
+ :doc => [short_doc, long_doc],
536
+ :possible_values => %w{ruby none},
537
+ :lowercase => true
538
+ end
441
539
 
442
- def automatic_osdeps_mode
443
- if mode = ENV['AUTOPROJ_AUTOMATIC_OSDEPS']
444
- mode =
445
- if mode == 'true' then AUTOMATIC
446
- elsif mode == 'false' then MANUAL
447
- elsif mode == 'wait' then WAIT
448
- else ASK
449
- end
450
- Autoproj.change_option('automatic_osdeps', mode, true)
451
- mode
540
+ def self.osdeps_mode_option_supported_os
541
+ long_doc =<<-EOT
542
+ The software packages that autoproj will have to build may require other
543
+ prepackaged softwares (a.k.a. OS dependencies) to be installed (RubyGems
544
+ packages, packages from your operating system/distribution, ...). Autoproj
545
+ is able to install those automatically for you.
546
+
547
+ Advanced users may want to control this behaviour. Additionally, the
548
+ installation of some packages require administration rights, which you may
549
+ not have. This option is meant to allow you to control autoproj's behaviour
550
+ while handling OS dependencies.
551
+
552
+ * if you say "all", it will install all packages automatically.
553
+ This requires root access thru 'sudo'
554
+ * if you say "ruby", only the Ruby packages will be installed.
555
+ Installing these packages does not require root access.
556
+ * if you say "os", only the OS-provided packages will be installed.
557
+ Installing these packages requires root access.
558
+ * if you say "none", autoproj will not do anything related to the
559
+ OS dependencies.
560
+
561
+ As any configuration value, the mode can be changed anytime by calling
562
+ an autoproj operation with the --reconfigure option (e.g. autoproj update
563
+ --reconfigure).
564
+
565
+ Finally, OS dependencies can be installed by calling "autoproj osdeps"
566
+ with the corresponding option (--all, --ruby, --os or --none).
567
+ EOT
568
+ message = [ "Which prepackaged software (a.k.a. 'osdeps') should autoproj install automatically (all, ruby, os, none) ?", long_doc.strip ]
569
+
570
+ Autoproj.configuration_option 'osdeps_mode', 'string',
571
+ :default => 'all',
572
+ :doc => message,
573
+ :possible_values => %w{all ruby os none},
574
+ :lowercase => true
575
+ end
576
+
577
+ def self.define_osdeps_mode_option
578
+ if supported_operating_system?
579
+ osdeps_mode_option_supported_os
452
580
  else
453
- Autoproj.user_config('automatic_osdeps')
581
+ osdeps_mode_option_unsupported_os
454
582
  end
455
583
  end
456
584
 
457
- # Requests the installation of the given set of packages
458
- def install(packages, package_osdeps = Hash.new)
459
- handled_os = OSDependencies.supported_operating_system?
460
- osdeps, gems = partition_packages(packages, package_osdeps)
461
- gems = filter_uptodate_gems(gems)
462
- if osdeps.empty? && gems.empty?
463
- return
585
+ def self.osdeps_mode_string_to_value(string)
586
+ string = string.downcase
587
+ case string
588
+ when 'all' then HANDLE_ALL
589
+ when 'ruby' then HANDLE_RUBY
590
+ when 'os' then HANDLE_OS
591
+ when 'none' then HANDLE_NONE
592
+ else raise ArgumentError, "invalid osdeps mode string '#{string}'"
464
593
  end
594
+ end
465
595
 
466
- if automatic_osdeps_mode == AUTOMATIC && !handled_os && !osdeps.empty?
467
- puts
468
- puts Autoproj.color("==============================", :bold)
469
- puts Autoproj.color("The packages that will be built require some other software to be installed", :bold)
470
- puts " " + osdeps.join("\n ")
471
- puts Autoproj.color("==============================", :bold)
472
- puts
473
- end
474
-
475
- if !OSDependencies.force_osdeps && automatic_osdeps_mode != AUTOMATIC
476
- puts
477
- puts Autoproj.color("==============================", :bold)
478
- puts Autoproj.color("The packages that will be built require some other software to be installed", :bold)
479
- puts
480
- if !osdeps.empty?
481
- puts "From the operating system:"
482
- puts " " + osdeps.join("\n ")
483
- puts
484
- end
485
- if !gems.empty?
486
- puts "From RubyGems:"
487
- puts " " + gems.join("\n ")
488
- puts
489
- end
596
+ # If set to true (the default), #install will try to remove the list of
597
+ # already uptodate packages from the installed packages. Set to false to
598
+ # install all packages regardless of their status
599
+ attr_accessor :filter_uptodate_packages
600
+
601
+ # Override the osdeps mode
602
+ def osdeps_mode=(value)
603
+ @osdeps_mode = OSDependencies.osdeps_mode_string_to_value(value)
604
+ end
605
+
606
+ # Returns the osdeps mode chosen by the user
607
+ def osdeps_mode
608
+ # This has two uses. It caches the value extracted from the
609
+ # AUTOPROJ_OSDEPS_MODE and/or configuration file. Moreover, it
610
+ # allows to override the osdeps mode by using
611
+ # OSDependencies#osdeps_mode=
612
+ if @osdeps_mode
613
+ return @osdeps_mode
614
+ end
490
615
 
491
- if automatic_osdeps_mode == ASK
492
- if !handled_os
493
- if gems.empty?
494
- # Nothing we can do, but the users required "ASK".
495
- # So, at least, let him press enter
496
- print "There are external packages, but I can't install them on this OS. Press ENTER to continue"
497
- STDOUT.flush
498
- STDIN.readline
499
- do_osdeps = false
500
- else
501
- print "Should I install the RubyGems packages ? [yes] "
616
+ @osdeps_mode = OSDependencies.osdeps_mode
617
+ end
618
+
619
+ def self.osdeps_mode
620
+ puts caller.join("\n ")
621
+ while true
622
+ mode =
623
+ if !Autoproj.has_config_key?('osdeps_mode') &&
624
+ mode_name = ENV['AUTOPROJ_OSDEPS_MODE']
625
+ begin OSDependencies.osdeps_mode_string_to_value(mode_name)
626
+ rescue ArgumentError
627
+ Autoproj.warn "invalid osdeps mode given through AUTOPROJ_OSDEPS_MODE (#{mode})"
628
+ nil
502
629
  end
503
630
  else
504
- print "Should I install these packages ? [yes] "
505
- end
506
- STDOUT.flush
507
-
508
- do_osdeps = nil
509
- while do_osdeps.nil?
510
- answer = STDIN.readline.chomp
511
- if answer == ''
512
- do_osdeps = true
513
- elsif answer == "no"
514
- do_osdeps = false
515
- elsif answer == 'yes'
516
- do_osdeps = true
517
- else
518
- print "invalid answer. Please answer with 'yes' or 'no' "
519
- STDOUT.flush
631
+ mode_name = Autoproj.user_config('osdeps_mode')
632
+ begin OSDependencies.osdeps_mode_string_to_value(mode_name)
633
+ rescue ArgumentError
634
+ Autoproj.warn "invalid osdeps mode stored in configuration file"
635
+ nil
520
636
  end
521
637
  end
638
+
639
+ if mode
640
+ @osdeps_mode = mode
641
+ return mode
642
+ end
643
+
644
+ # Invalid configuration values. Retry
645
+ Autoproj.reset_option('osdeps_mode')
646
+ ENV['AUTOPROJ_OSDEPS_MODE'] = nil
647
+ end
648
+ end
649
+
650
+ # The set of packages that have already been installed
651
+ attr_reader :installed_packages
652
+
653
+ def osdeps_interaction_unknown_os(osdeps)
654
+ puts <<-EOMSG
655
+ #{Autoproj.color("The build process requires some other software packages to be installed on our operating system", :bold)}
656
+ #{Autoproj.color("If they are already installed, simply ignore this message", :red)}"
657
+
658
+ #{osdeps.join("\n ")}
659
+
660
+ EOMSG
661
+ print Autoproj.color("Press ENTER to continue", :bold)
662
+ STDOUT.flush
663
+ STDIN.readline
664
+ puts
665
+ nil
666
+ end
667
+
668
+ def osdeps_interaction(osdeps, os_packages, shell_script, silent)
669
+ if !OSDependencies.supported_operating_system?
670
+ if silent
671
+ return false
522
672
  else
523
- puts "Since you requested autoproj to not handle the osdeps automatically, you have to"
524
- puts "do it yourself. Alternatively, you can run 'autoproj osdeps' and/or change to"
525
- puts "automatic osdeps handling by running an autoproj operation with the --reconfigure"
526
- puts "option (e.g. autoproj build --reconfigure)"
527
- puts Autoproj.color("==============================", :bold)
528
- puts
529
-
530
- if automatic_osdeps_mode == WAIT
531
- print "Press ENTER to continue "
532
- STDOUT.flush
533
- STDIN.readline
534
- end
673
+ return osdeps_interaction_unknown_os(osdeps)
535
674
  end
675
+ elsif OSDependencies.force_osdeps
676
+ return true
677
+ elsif osdeps_mode == HANDLE_ALL || osdeps_mode == HANDLE_OS
678
+ return true
679
+ elsif silent
680
+ return false
681
+ end
682
+
683
+ # We're asked to not install the OS packages but to display them
684
+ # anyway, do so now
685
+ puts <<-EOMSG
686
+
687
+ #{Autoproj.color("The build process and/or the packages require some other software to be installed", :bold)}
688
+ #{Autoproj.color("and you required autoproj to not install them itself", :bold)}
689
+ #{Autoproj.color("\nIf these packages are already installed, simply ignore this message\n", :red) if !can_filter_uptodate_packages?}
690
+ The following packages are available as OS dependencies, i.e. as prebuilt
691
+ packages provided by your distribution / operating system. You will have to
692
+ install them manually if they are not already installed
693
+
694
+ #{os_packages.sort.join("\n ")}
695
+
696
+ the following command line(s) can be run as root to install them:
697
+
698
+ #{shell_script.split("\n").join("\n| ")}
699
+
700
+ EOMSG
701
+ print " #{Autoproj.color("Press ENTER to continue ", :bold)}"
702
+ STDOUT.flush
703
+ STDIN.readline
704
+ puts
705
+ false
706
+ end
707
+
708
+ def gems_interaction(gems, cmdline, silent)
709
+ if OSDependencies.force_osdeps
710
+ return true
711
+ elsif osdeps_mode == HANDLE_ALL || osdeps_mode == HANDLE_RUBY
712
+ return true
713
+ elsif silent
714
+ return false
715
+ end
716
+
717
+ # We're not supposed to install rubygem packages but silent is not
718
+ # set, so display information about them anyway
719
+ puts <<-EOMSG
720
+ #{Autoproj.color("The build process and/or the packages require some Ruby Gems to be installed", :bold)}
721
+ #{Autoproj.color("and you required autoproj to not do it itself", :bold)}
722
+ You can use the --all or --ruby options to autoproj osdeps to install these
723
+ packages anyway, and/or change to the osdeps handling mode by running an
724
+ autoproj operation with the --reconfigure option as for instance
725
+ autoproj build --reconfigure
726
+
727
+ The following command line can be used to install them manually
728
+
729
+ #{cmdline.join(" ")}
730
+
731
+ Autoproj expects these Gems to be installed in #{Autoproj.gem_home} This can
732
+ be overriden by setting the AUTOPROJ_GEM_HOME environment variable manually
733
+
734
+ EOMSG
735
+ print " #{Autoproj.color("Press ENTER to continue ", :bold)}"
736
+
737
+ STDOUT.flush
738
+ STDIN.readline
739
+ puts
740
+ false
741
+ end
536
742
 
537
- if !do_osdeps
538
- return
743
+ # Requests the installation of the given set of packages
744
+ def install(packages, package_osdeps = Hash.new)
745
+ handled_os = OSDependencies.supported_operating_system?
746
+ # Remove the set of packages that have already been installed
747
+ packages -= installed_packages
748
+ return if packages.empty?
749
+
750
+ osdeps, gems = partition_packages(packages, package_osdeps)
751
+ if handled_os
752
+ os_name, os_version = OSDependencies.operating_system
753
+ os_packages = resolve_os_dependencies(osdeps)
754
+ if filter_uptodate_packages
755
+ os_packages = filter_uptodate_os_packages(os_packages, os_name)
539
756
  end
540
757
  end
758
+ if filter_uptodate_packages
759
+ gems = filter_uptodate_gems(gems)
760
+ end
541
761
 
542
762
  did_something = false
543
763
 
544
- if handled_os && !osdeps.empty?
545
- shell_script = generate_os_script(osdeps)
546
- if Autoproj.verbose
547
- Autoproj.progress "Installing non-ruby OS dependencies with"
548
- Autoproj.progress shell_script
764
+ if !osdeps.empty? && (!os_packages || !os_packages.empty?)
765
+ if handled_os
766
+ shell_script = generate_auto_os_script(os_name, os_packages)
767
+ user_shell_script = generate_user_os_script(os_name, os_packages)
549
768
  end
769
+ if osdeps_interaction(osdeps, os_packages, user_shell_script, silent?)
770
+ Autoproj.progress " installing OS packages: #{os_packages.sort.join(", ")}"
550
771
 
551
- File.open('osdeps.sh', 'w') do |file|
552
- file.write shell_script
553
- end
554
- Autobuild.progress "installing/updating OS dependencies: #{osdeps.join(", ")}"
555
- begin
556
- Autobuild::Subprocess.run 'autoproj', 'osdeps', '/bin/bash', File.expand_path('osdeps.sh')
557
- ensure
558
- FileUtils.rm_f 'osdeps.sh'
559
- end
560
- did_something ||= true
561
- end
772
+ if Autoproj.verbose
773
+ Autoproj.progress "Generating installation script for non-ruby OS dependencies"
774
+ Autoproj.progress shell_script
775
+ end
562
776
 
563
- if !gems.empty?
564
- gems = filter_uptodate_gems(gems)
777
+ Tempfile.open('osdeps_sh') do |io|
778
+ io.puts "#! /bin/bash"
779
+ io.puts GAIN_ROOT_ACCESS
780
+ io.write shell_script
781
+ io.flush
782
+ Autobuild::Subprocess.run 'autoproj', 'osdeps', '/bin/bash', io.path
783
+ end
784
+ did_something = true
785
+ end
565
786
  end
566
787
 
567
- # Now install what is left
788
+ # Now install the RubyGems
568
789
  if !gems.empty?
569
790
  guess_gem_program
570
- if Autoproj.verbose
571
- Autoproj.progress "Installing rubygems dependencies with"
572
- Autoproj.progress "gem install #{gems.join(" ")}"
573
- end
574
791
 
575
792
  cmdline = [Autobuild.tool('gem'), 'install']
576
793
  if Autoproj::OSDependencies.gem_with_prerelease
@@ -578,9 +795,11 @@ module Autoproj
578
795
  end
579
796
  cmdline.concat(gems)
580
797
 
581
- Autobuild.progress "installing/updating RubyGems dependencies: #{gems.join(", ")}"
582
- Autobuild::Subprocess.run 'autoproj', 'osdeps', *cmdline
583
- did_something ||= true
798
+ if gems_interaction(gems, cmdline, silent?)
799
+ Autobuild.progress "installing/updating RubyGems dependencies: #{gems.sort.join(", ")}"
800
+ Autobuild::Subprocess.run 'autoproj', 'osdeps', *cmdline
801
+ did_something = true
802
+ end
584
803
  end
585
804
 
586
805
  did_something