autoproj 2.0.0.rc3 → 2.0.0.rc4

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +9 -29
  3. data/bin/autoproj_bootstrap +159 -3150
  4. data/bin/autoproj_bootstrap.in +4 -256
  5. data/bin/autoproj_install +225 -0
  6. data/bin/autoproj_install.in +14 -0
  7. data/lib/autoproj.rb +2 -1
  8. data/lib/autoproj/autobuild.rb +2 -2
  9. data/lib/autoproj/cli/bootstrap.rb +0 -39
  10. data/lib/autoproj/cli/build.rb +0 -3
  11. data/lib/autoproj/cli/main.rb +13 -1
  12. data/lib/autoproj/cli/osdeps.rb +1 -1
  13. data/lib/autoproj/cli/show.rb +1 -1
  14. data/lib/autoproj/cli/update.rb +4 -4
  15. data/lib/autoproj/cli/upgrade.rb +71 -0
  16. data/lib/autoproj/configuration.rb +18 -1
  17. data/lib/autoproj/exceptions.rb +7 -0
  18. data/lib/autoproj/installation_manifest.rb +23 -12
  19. data/lib/autoproj/manifest.rb +22 -48
  20. data/lib/autoproj/ops/build.rb +2 -2
  21. data/lib/autoproj/ops/configuration.rb +1 -1
  22. data/lib/autoproj/ops/import.rb +1 -1
  23. data/lib/autoproj/ops/install.rb +211 -0
  24. data/lib/autoproj/ops/main_config_switcher.rb +1 -5
  25. data/lib/autoproj/os_package_installer.rb +348 -0
  26. data/lib/autoproj/{osdeps.rb → os_package_resolver.rb} +56 -392
  27. data/lib/autoproj/package_managers/apt_dpkg_manager.rb +2 -2
  28. data/lib/autoproj/package_managers/bundler_manager.rb +179 -0
  29. data/lib/autoproj/package_managers/emerge_manager.rb +2 -2
  30. data/lib/autoproj/package_managers/gem_manager.rb +7 -6
  31. data/lib/autoproj/package_managers/homebrew_manager.rb +2 -2
  32. data/lib/autoproj/package_managers/manager.rb +5 -6
  33. data/lib/autoproj/package_managers/pacman_manager.rb +2 -2
  34. data/lib/autoproj/package_managers/pip_manager.rb +8 -8
  35. data/lib/autoproj/package_managers/pkg_manager.rb +2 -2
  36. data/lib/autoproj/package_managers/port_manager.rb +2 -2
  37. data/lib/autoproj/package_managers/shell_script_manager.rb +4 -4
  38. data/lib/autoproj/package_managers/unknown_os_manager.rb +2 -2
  39. data/lib/autoproj/package_managers/yum_manager.rb +2 -2
  40. data/lib/autoproj/package_managers/zypper_manager.rb +2 -2
  41. data/lib/autoproj/package_set.rb +10 -10
  42. data/lib/autoproj/reporter.rb +3 -2
  43. data/lib/autoproj/system.rb +1 -4
  44. data/lib/autoproj/version.rb +1 -1
  45. data/lib/autoproj/workspace.rb +155 -32
  46. metadata +9 -3
@@ -19,10 +19,10 @@ def initialize(manifest)
19
19
  # It rebuilds (i.e. does a clean + build) of all packages declared
20
20
  # in the manifest's layout. It also performs a reinstall of all
21
21
  # non-OS-specific managers that support it (e.g. RubyGems) if
22
- # {update_os_dependencies?} is set to true (the default)
22
+ # {update_os_packages?} is set to true (the default)
23
23
  def rebuild_all
24
24
  packages = manifest.all_layout_packages
25
- manifest.pristine_os_dependencies(packages)
25
+ manifest.pristine_os_packages(packages)
26
26
  rebuild_packages(packages, packages)
27
27
  end
28
28
 
@@ -140,7 +140,7 @@ def update_remote_package_set(vcs, options = Hash.new)
140
140
  Autoproj.message("autoproj: updating remote definitions of package sets", :bold)
141
141
  @remote_update_message_displayed = true
142
142
  end
143
- ws.osdeps.install([vcs.type])
143
+ ws.install_os_packages([vcs.type])
144
144
  update_configuration_repository(
145
145
  vcs, name, raw_local_dir, options)
146
146
  end
@@ -28,7 +28,7 @@ def mark_exclusion_along_revdeps(pkg_name, revdeps, chain = [], reason = nil)
28
28
  end
29
29
 
30
30
  VALID_OSDEP_AVAILABILITY =
31
- [OSDependencies::AVAILABLE, OSDependencies::IGNORE]
31
+ [OSPackageResolver::AVAILABLE, OSPackageResolver::IGNORE]
32
32
 
33
33
  def import_next_step(pkg, reverse_dependencies)
34
34
  new_packages = []
@@ -0,0 +1,211 @@
1
+ require 'optparse'
2
+ require 'fileutils'
3
+ require 'yaml'
4
+
5
+ module Autoproj
6
+ module Ops
7
+ # This class contains the functionality necessary to install autoproj in a
8
+ # clean root
9
+ #
10
+ # It can be required standalone (i.e. does not depend on anything else than
11
+ # ruby and the ruby standard library)
12
+ class Install
13
+ # The directory in which to install autoproj
14
+ attr_reader :root_dir
15
+ # Content of the Gemfile generated to install autoproj itself
16
+ attr_accessor :gemfile
17
+
18
+ def initialize(root_dir)
19
+ @root_dir = root_dir
20
+ @gemfile = default_gemfile_contents
21
+ @private_bundler = false
22
+ @private_autoproj = false
23
+ @private_gems = false
24
+ end
25
+
26
+ def dot_autoproj; File.join(root_dir, '.autoproj') end
27
+ def bin_dir; File.join(dot_autoproj, 'bin') end
28
+ def bundler_install_dir; File.join(dot_autoproj, 'bundler') end
29
+ def autoproj_install_dir; File.join(dot_autoproj, 'autoproj') end
30
+ # The path to the gemfile used to install autoproj
31
+ def autoproj_gemfile_path; File.join(autoproj_install_dir, 'Gemfile') end
32
+ def autoproj_config_path; File.join(dot_autoproj, 'config.yml') end
33
+
34
+ # Whether bundler should be installed locally in {#dot_autoproj}
35
+ def private_bundler?; @private_bundler end
36
+ # Whether autoproj should be installed locally in {#dot_autoproj}
37
+ def private_autoproj?; @private_autoproj end
38
+ # Whether bundler should be installed locally in the workspace
39
+ # prefix directory
40
+ def private_gems?; @private_gems end
41
+
42
+ def guess_gem_program
43
+ ruby_bin = RbConfig::CONFIG['RUBY_INSTALL_NAME']
44
+ ruby_bindir = RbConfig::CONFIG['bindir']
45
+
46
+ candidates = ['gem']
47
+ if ruby_bin =~ /^ruby(.+)$/
48
+ candidates << "gem#{$1}"
49
+ end
50
+
51
+ candidates.each do |gem_name|
52
+ if File.file?(gem_full_path = File.join(ruby_bindir, gem_name))
53
+ return gem_full_path
54
+ end
55
+ end
56
+ raise ArgumentError, "cannot find a gem program (tried #{candidates.sort.join(", ")} in #{ruby_bindir})"
57
+ end
58
+
59
+ # The content of the default {#gemfile}
60
+ #
61
+ # @param [String] autoproj_version a constraint on the autoproj version
62
+ # that should be used
63
+ # @return [String]
64
+ def default_gemfile_contents(autoproj_version = ">= 0")
65
+ ["source \"https://rubygems.org\"",
66
+ "gem \"autoproj\", \"#{autoproj_version}\""].join("\n")
67
+ end
68
+
69
+ # Parse the provided command line options and returns the non-options
70
+ def parse_options(args = ARGV)
71
+ options = OptionParser.new do |opt|
72
+ opt.on '--private-bundler', 'install bundler locally in the workspace' do
73
+ @private_bundler = true
74
+ end
75
+ opt.on '--private-autoproj', 'install autoproj locally in the workspace' do
76
+ @private_autoproj = true
77
+ end
78
+ opt.on '--private-gems', 'install gems locally in the prefix directory' do
79
+ @private_gems = true
80
+ end
81
+ opt.on '--private', 'whether bundler, autoproj and the workspace gems should be installed locally in the workspace' do
82
+ @private_bundler = true
83
+ @private_autoproj = true
84
+ @private_gems = true
85
+ end
86
+ opt.on '--version=VERSION_CONSTRAINT', String, 'use the provided string as a version constraint for autoproj' do |version|
87
+ @gemfile = default_gemfile_contents(version)
88
+ end
89
+ opt.on '--gemfile=PATH', String, 'use the given Gemfile to install autoproj instead of the default' do |path|
90
+ @gemfile = File.read(path)
91
+ end
92
+ end
93
+ options.parse(ARGV)
94
+ end
95
+
96
+ def install_bundler
97
+ gem_program = guess_gem_program
98
+ puts "Detected 'gem' to be #{gem_program}"
99
+
100
+ result = system(
101
+ Hash['GEM_PATH' => nil,
102
+ 'GEM_HOME' => bundler_install_dir],
103
+ gem_program, 'install', '--no-document', '--no-user-install', '--no-format-executable',
104
+ "--bindir=#{File.join(bundler_install_dir, 'bin')}", 'bundler')
105
+
106
+ if !result
107
+ STDERR.puts "FATAL: failed to install bundler in #{dot_autoproj}"
108
+ exit 1
109
+ end
110
+ File.join(bin_dir, 'bundler')
111
+ end
112
+
113
+ def save_env_sh
114
+ env = Autobuild::Environment.new
115
+ path = []
116
+ if private_bundler?
117
+ env.push_path 'PATH', File.join(bundler_install_dir, 'bin')
118
+ env.push_path 'GEM_PATH', bundler_install_dir
119
+ end
120
+ env.push_path 'PATH', File.join(autoproj_install_dir, 'bin')
121
+ env.inherit 'PATH'
122
+ if private_autoproj?
123
+ env.push_path 'GEM_PATH', autoproj_install_dir
124
+ end
125
+
126
+ # Generate environment files right now, we can at least use bundler
127
+ File.open(File.join(dot_autoproj, 'env.sh'), 'w') do |io|
128
+ env.export_env_sh(io)
129
+ end
130
+
131
+ File.open(File.join(root_dir, 'env.sh'), 'w') do |io|
132
+ io.write <<-EOSHELL
133
+ source "#{File.join(dot_autoproj, 'env.sh')}"
134
+ export AUTOPROJ_CURRENT_ROOT=#{root_dir}
135
+ EOSHELL
136
+ end
137
+ end
138
+
139
+ def save_gemfile
140
+ FileUtils.mkdir_p File.dirname(autoproj_gemfile_path)
141
+ File.open(autoproj_gemfile_path, 'w') do |io|
142
+ io.write gemfile
143
+ end
144
+ end
145
+
146
+ def install_autoproj(bundler)
147
+ # Force bundler to update. If the user does not want this, let him specify a
148
+ # Gemfile with tighter version constraints
149
+ lockfile = File.join(File.dirname(autoproj_gemfile_path), 'Gemfile.lock')
150
+ if File.exist?(lockfile)
151
+ FileUtils.rm lockfile
152
+ end
153
+
154
+ env = Hash['BUNDLE_GEMFILE' => nil, 'RUBYLIB' => nil]
155
+ opts = Array.new
156
+
157
+ if private_autoproj?
158
+ env = Hash['GEM_PATH' => bundler_install_dir,
159
+ 'GEM_HOME' => nil]
160
+ opts << "--clean" << "--path=#{autoproj_install_dir}"
161
+ end
162
+
163
+ result = system(env,
164
+ bundler, 'install',
165
+ "--gemfile=#{autoproj_gemfile_path}",
166
+ "--binstubs=#{File.join(autoproj_install_dir, 'bin')}",
167
+ *opts)
168
+ if !result
169
+ STDERR.puts "FATAL: failed to install autoproj in #{dot_autoproj}"
170
+ exit 1
171
+ end
172
+ end
173
+
174
+ def update_configuration
175
+ if File.exist?(autoproj_config_path)
176
+ config = YAML.load(File.read(autoproj_config_path)) || Hash.new
177
+ else
178
+ config = Hash.new
179
+ end
180
+ config['private_bundler'] = private_bundler?
181
+ config['private_autoproj'] = private_autoproj?
182
+ config['private_gems'] = private_gems?
183
+ File.open(autoproj_config_path, 'w') do |io|
184
+ YAML.dump(config, io)
185
+ end
186
+ end
187
+
188
+ def install
189
+ if private_bundler?
190
+ puts "Installing bundler in #{bundler_install_dir}"
191
+ bundler = install_bundler
192
+ end
193
+ save_gemfile
194
+ puts "Installing autoproj in #{dot_autoproj}"
195
+ install_autoproj(bundler || 'bundler')
196
+ end
197
+
198
+ # Actually perform the install
199
+ def run
200
+ install
201
+ ENV['BUNDLE_GEMFILE'] = autoproj_gemfile_path
202
+ require 'bundler'
203
+ Bundler.setup
204
+ require 'autobuild'
205
+ save_env_sh
206
+ update_configuration
207
+ end
208
+ end
209
+ end
210
+ end
211
+
@@ -81,10 +81,6 @@ def bootstrap(buildconf_info, options = Hash.new)
81
81
  validate_autoproj_current_root(options[:reuse])
82
82
 
83
83
  ws.config.validate_ruby_executable
84
-
85
- PackageManagers::GemManager.with_prerelease(ws.config.use_prerelease?) do
86
- ws.osdeps.install(%w{autobuild autoproj})
87
- end
88
84
  ws.config.set 'reused_autoproj_installations', options[:reuse], true
89
85
  ws.env.export_env_sh(nil, shell_helpers: ws.config.shell_helpers?)
90
86
 
@@ -174,7 +170,7 @@ def do_switch_config(delete_current, type, url, *options)
174
170
  vcs = VCSDefinition.from_raw(vcs_def)
175
171
 
176
172
  # Install the OS dependencies required for this VCS
177
- ws.osdeps.install([vcs.type])
173
+ ws.install_os_packages([vcs.type])
178
174
 
179
175
  # Now check out the actual configuration
180
176
  config_dir = File.join(ws.root_dir, "autoproj")
@@ -0,0 +1,348 @@
1
+ require 'autoproj/package_managers/manager'
2
+ require 'autoproj/package_managers/unknown_os_manager'
3
+ require 'autoproj/package_managers/shell_script_manager'
4
+
5
+ require 'autoproj/package_managers/apt_dpkg_manager'
6
+ require 'autoproj/package_managers/emerge_manager'
7
+ require 'autoproj/package_managers/homebrew_manager'
8
+ require 'autoproj/package_managers/pacman_manager'
9
+ require 'autoproj/package_managers/pkg_manager'
10
+ require 'autoproj/package_managers/port_manager'
11
+ require 'autoproj/package_managers/yum_manager'
12
+ require 'autoproj/package_managers/zypper_manager'
13
+
14
+ require 'autoproj/package_managers/bundler_manager'
15
+ require 'autoproj/package_managers/pip_manager'
16
+
17
+ module Autoproj
18
+ class OSPackageInstaller
19
+ attr_reader :ws
20
+
21
+ PACKAGE_MANAGERS = Hash[
22
+ 'apt-dpkg' => PackageManagers::AptDpkgManager,
23
+ 'gem' => PackageManagers::BundlerManager,
24
+ 'emerge' => PackageManagers::EmergeManager,
25
+ 'brew' => PackageManagers::PacmanManager,
26
+ 'pacman' => PackageManagers::HomebrewManager,
27
+ 'pip' => PackageManagers::YumManager,
28
+ 'pkg' => PackageManagers::PortManager,
29
+ 'macports' => PackageManagers::ZypperManager,
30
+ 'yum' => PackageManagers::PipManager ,
31
+ 'zypper' => PackageManagers::PkgManager
32
+ ]
33
+
34
+ attr_reader :os_package_resolver
35
+
36
+ # The set of packages that have already been installed
37
+ attr_reader :installed_packages
38
+
39
+ attr_writer :silent
40
+ def silent?; @silent end
41
+
42
+ class << self
43
+ attr_accessor :force_osdeps
44
+ end
45
+
46
+ def initialize(ws, os_package_resolver)
47
+ @ws = ws
48
+ @os_package_resolver = os_package_resolver
49
+ @installed_packages = Set.new
50
+ @silent = true
51
+ @filter_uptodate_packages = true
52
+ end
53
+
54
+ # Returns the package manager object for the current OS
55
+ def os_package_manager
56
+ if !@os_package_manager
57
+ name = os_package_resolver.os_package_manager
58
+ @os_package_manager = package_managers[name] ||
59
+ PackageManagers::UnknownOSManager.new(ws)
60
+ end
61
+ return @os_package_manager
62
+ end
63
+
64
+ # Returns the set of package managers
65
+ def package_managers
66
+ if !@package_managers
67
+ @package_managers = Hash.new
68
+ PACKAGE_MANAGERS.each do |name, klass|
69
+ @package_managers[name] = klass.new(ws)
70
+ end
71
+ end
72
+ @package_managers
73
+ end
74
+
75
+ def each_manager(&block)
76
+ package_managers.each_value(&block)
77
+ end
78
+
79
+ HANDLE_ALL = 'all'
80
+ HANDLE_RUBY = 'ruby'
81
+ HANDLE_OS = 'os'
82
+ HANDLE_NONE = 'none'
83
+
84
+ def osdeps_mode_option_unsupported_os(config)
85
+ long_doc =<<-EOT
86
+ The software packages that autoproj will have to build may require other
87
+ prepackaged softwares (a.k.a. OS dependencies) to be installed (RubyGems
88
+ packages, packages from your operating system/distribution, ...). Autoproj is
89
+ usually able to install those automatically, but unfortunately your operating
90
+ system is not (yet) supported by autoproj's osdeps mechanism, it can only offer
91
+ you some limited support.
92
+
93
+ Some package handlers are cross-platform, and are therefore supported. However,
94
+ you will have to install the kind of OS dependencies (so-called OS packages)
95
+
96
+ This option is meant to allow you to control autoproj's behaviour while handling
97
+ OS dependencies.
98
+
99
+ * if you say "all", all OS-independent packages are going to be installed.
100
+ * if you say "gem", the RubyGem packages will be installed.
101
+ * if you say "pip", the Pythin PIP packages will be installed.
102
+ * if you say "none", autoproj will not do anything related to the OS
103
+ dependencies.
104
+
105
+ As any configuration value, the mode can be changed anytime by calling
106
+ autoproj reconfigure
107
+
108
+ Finally, the "autoproj osdeps" command will give you the necessary information
109
+ about the OS packages that you will need to install manually.
110
+
111
+ So, what do you want ? (all, none or a comma-separated list of: gem pip)
112
+ EOT
113
+ message = [ "Which prepackaged software (a.k.a. 'osdeps') should autoproj install automatically (all, none or a comma-separated list of: gem pip) ?", long_doc.strip ]
114
+
115
+ config.declare 'osdeps_mode', 'string',
116
+ default: 'ruby',
117
+ doc: message,
118
+ lowercase: true
119
+ end
120
+
121
+ def osdeps_mode_option_supported_os(config)
122
+ long_doc =<<-EOT
123
+ The software packages that autoproj will have to build may require other
124
+ prepackaged softwares (a.k.a. OS dependencies) to be installed (RubyGems
125
+ packages, packages from your operating system/distribution, ...). Autoproj
126
+ is able to install those automatically for you.
127
+
128
+ Advanced users may want to control this behaviour. Additionally, the
129
+ installation of some packages require administration rights, which you may
130
+ not have. This option is meant to allow you to control autoproj's behaviour
131
+ while handling OS dependencies.
132
+
133
+ * if you say "all", it will install all packages automatically.
134
+ This requires root access thru 'sudo'
135
+ * if you say "pip", only the Ruby packages will be installed.
136
+ Installing these packages does not require root access.
137
+ * if you say "gem", only the Ruby packages will be installed.
138
+ Installing these packages does not require root access.
139
+ * if you say "os", only the OS-provided packages will be installed.
140
+ Installing these packages requires root access.
141
+ * if you say "none", autoproj will not do anything related to the
142
+ OS dependencies.
143
+
144
+ Finally, you can provide a comma-separated list of pip gem and os.
145
+
146
+ As any configuration value, the mode can be changed anytime by calling
147
+ autoproj reconfigure
148
+
149
+ Finally, the "autoproj osdeps" command will give you the necessary information
150
+ about the OS packages that you will need to install manually.
151
+
152
+ So, what do you want ? (all, none or a comma-separated list of: os gem pip)
153
+ EOT
154
+ message = [ "Which prepackaged software (a.k.a. 'osdeps') should autoproj install automatically (all, none or a comma-separated list of: os gem pip) ?", long_doc.strip ]
155
+
156
+ config.declare 'osdeps_mode', 'string',
157
+ default: 'all',
158
+ doc: message,
159
+ lowercase: true
160
+ end
161
+
162
+ def define_osdeps_mode_option
163
+ if OSPackageResolver.supported_operating_system?
164
+ osdeps_mode_option_supported_os(ws.config)
165
+ else
166
+ osdeps_mode_option_unsupported_os(ws.config)
167
+ end
168
+ end
169
+
170
+ def osdeps_mode_string_to_value(string)
171
+ string = string.to_s.downcase.split(',')
172
+ modes = []
173
+ string.map do |str|
174
+ case str
175
+ when 'all' then modes.concat(['os', 'gem', 'pip'])
176
+ when 'ruby' then modes << 'gem'
177
+ when 'gem' then modes << 'gem'
178
+ when 'pip' then modes << 'pip'
179
+ when 'os' then modes << 'os'
180
+ when 'none' then
181
+ else raise ArgumentError, "#{str} is not a known package handler"
182
+ end
183
+ end
184
+ modes
185
+ end
186
+
187
+ # If set to true (the default), #install will try to remove the list of
188
+ # already uptodate packages from the installed packages. Set to false to
189
+ # install all packages regardless of their status
190
+ attr_writer :filter_uptodate_packages
191
+
192
+ # If set to true (the default), #install will try to remove the list of
193
+ # already uptodate packages from the installed packages. Use
194
+ # #filter_uptodate_packages= to set it to false to install all packages
195
+ # regardless of their status
196
+ def filter_uptodate_packages?
197
+ !!@filter_uptodate_packages
198
+ end
199
+
200
+ # Override the osdeps mode
201
+ def osdeps_mode=(value)
202
+ @osdeps_mode = osdeps_mode_string_to_value(value)
203
+ end
204
+
205
+ # Returns the osdeps mode chosen by the user
206
+ def osdeps_mode
207
+ # This has two uses. It caches the value extracted from the
208
+ # AUTOPROJ_OSDEPS_MODE and/or configuration file. Moreover, it
209
+ # allows to override the osdeps mode by using
210
+ # OSPackageInstaller#osdeps_mode=
211
+ if @osdeps_mode
212
+ return @osdeps_mode
213
+ end
214
+
215
+ config = ws.config
216
+ while true
217
+ mode =
218
+ if !config.has_value_for?('osdeps_mode') && mode_name = ENV['AUTOPROJ_OSDEPS_MODE']
219
+ begin osdeps_mode_string_to_value(mode_name)
220
+ rescue ArgumentError
221
+ Autoproj.warn "invalid osdeps mode given through AUTOPROJ_OSDEPS_MODE (#{mode})"
222
+ nil
223
+ end
224
+ else
225
+ mode_name = config.get('osdeps_mode')
226
+ begin osdeps_mode_string_to_value(mode_name)
227
+ rescue ArgumentError
228
+ Autoproj.warn "invalid osdeps mode stored in configuration file"
229
+ nil
230
+ end
231
+ end
232
+
233
+ if mode
234
+ @osdeps_mode = mode
235
+ config.set('osdeps_mode', mode_name, true)
236
+ return mode
237
+ end
238
+
239
+ # Invalid configuration values. Retry
240
+ config.reset('osdeps_mode')
241
+ ENV['AUTOPROJ_OSDEPS_MODE'] = nil
242
+ end
243
+ end
244
+
245
+ # Set up the registered package handlers according to the specified osdeps mode
246
+ #
247
+ # It enables/disables package handlers based on either the value
248
+ # returned by {#osdeps_mode} or the value passed as option (the latter
249
+ # takes precedence). Moreover, sets the handler's silent flag using
250
+ # {#silent?}
251
+ #
252
+ # @option options [Array<String>] the package handlers that should be
253
+ # enabled. The default value is returned by {#osdeps_mode}
254
+ # @return [Array<PackageManagers::Manager>] the set of enabled package
255
+ # managers
256
+ def setup_package_managers(options = Hash.new)
257
+ options = Kernel.validate_options options,
258
+ osdeps_mode: osdeps_mode
259
+
260
+ os_package_manager.enabled = false
261
+ package_managers.each_value do |handler|
262
+ handler.enabled = false
263
+ end
264
+ options[:osdeps_mode].each do |m|
265
+ if m == 'os'
266
+ os_package_manager.enabled = true
267
+ elsif pkg = package_managers[m]
268
+ pkg.enabled = true
269
+ else
270
+ Autoproj.warn "osdep handler #{m.inspect} has no handler, available handlers are #{package_managers.keys.map(&:inspect).sort.join(", ")}"
271
+ end
272
+ end
273
+ os_package_manager.silent = self.silent?
274
+ package_managers.each_value do |v|
275
+ v.silent = self.silent?
276
+ end
277
+
278
+ enabled_handlers = []
279
+ if os_package_manager.enabled?
280
+ enabled_handlers << os_package_manager
281
+ end
282
+ package_managers.each_value do |v|
283
+ if v.enabled?
284
+ enabled_handlers << v
285
+ end
286
+ end
287
+ enabled_handlers
288
+ end
289
+
290
+ # Requests that packages that are handled within the autoproj project
291
+ # (i.e. gems) are restored to pristine condition
292
+ #
293
+ # This is usually called as a rebuild step to make sure that all these
294
+ # packages are updated to whatever required the rebuild
295
+ def pristine(packages, options = Hash.new)
296
+ install(packages, options.merge(install_only: true))
297
+ packages = os_package_resolver.resolve_os_packages(packages)
298
+
299
+ _, other_packages =
300
+ packages.partition { |handler, list| handler == os_package_manager }
301
+ other_packages.each do |handler, list|
302
+ if handler.respond_to?(:pristine)
303
+ handler.pristine(list)
304
+ end
305
+ end
306
+ end
307
+
308
+ # Requests the installation of the given set of packages
309
+ def install(packages, options = Hash.new)
310
+ # Remove the set of packages that have already been installed
311
+ packages = packages.to_set - installed_packages
312
+ return false if packages.empty?
313
+
314
+ filter_options, options =
315
+ filter_options options, install_only: !Autobuild.do_update
316
+ setup_package_managers(options)
317
+
318
+ packages = os_package_resolver.resolve_os_packages(packages)
319
+ packages = packages.map do |handler_name, list|
320
+ [package_managers[handler_name], list]
321
+ end
322
+
323
+ needs_filter = (filter_uptodate_packages? || filter_options[:install_only])
324
+ packages = packages.map do |handler, list|
325
+ if needs_filter && handler.respond_to?(:filter_uptodate_packages)
326
+ list = handler.filter_uptodate_packages(list, filter_options)
327
+ end
328
+
329
+ if !list.empty?
330
+ [handler, list]
331
+ end
332
+ end.compact
333
+ return false if packages.empty?
334
+
335
+ # Install OS packages first, as the other package handlers might
336
+ # depend on OS packages
337
+ os_packages, other_packages = packages.partition { |handler, list| handler == os_package_manager }
338
+ [os_packages, other_packages].each do |packages|
339
+ packages.each do |handler, list|
340
+ handler.install(list)
341
+ @installed_packages |= list.to_set
342
+ end
343
+ end
344
+ true
345
+ end
346
+ end
347
+ end
348
+