autoproj 2.0.0.rc3 → 2.0.0.rc4

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