autoproj 1.6.1 → 1.6.2.rc2

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