class Autoproj::OSPackageInstaller
Constants
- HANDLE_ALL
- HANDLE_NONE
- HANDLE_OS
- HANDLE_RUBY
- PACKAGE_MANAGERS
Attributes
If set to true (the default), install
will try to remove the list of already uptodate packages from the installed packages. Set to false to install all packages regardless of their status
The set of resolved packages that have already been installed
Returns the set of package managers
Public Class Methods
Source
# File lib/autoproj/os_package_installer.rb, line 51 def initialize(ws, os_package_resolver, package_managers: PACKAGE_MANAGERS) @ws = ws @os_package_resolver = os_package_resolver @os_package_manager = nil @installed_resolved_packages = Hash.new { |h, k| h[k] = Set.new } @silent = true @filter_uptodate_packages = true @osdeps_mode = nil @package_managers = Hash.new package_managers.each do |name, klass| @package_managers[name] = klass.new(ws) end end
Public Instance Methods
Source
# File lib/autoproj/os_package_installer.rb, line 201 def configure_manager os_package_manager.configure_manager if osdeps_mode.include?("os") end
Source
# File lib/autoproj/os_package_installer.rb, line 170 def define_osdeps_mode_option if os_package_resolver.supported_operating_system? osdeps_mode_option_supported_os(ws.config) else osdeps_mode_option_unsupported_os(ws.config) end end
Source
# File lib/autoproj/os_package_installer.rb, line 79 def each_manager(&block) package_managers.each_value(&block) end
Source
# File lib/autoproj/os_package_installer.rb, line 83 def each_manager_with_name(&block) package_managers.each(&block) end
Source
# File lib/autoproj/os_package_installer.rb, line 214 def filter_uptodate_packages? !!@filter_uptodate_packages end
If set to true (the default), install
will try to remove the list of already uptodate packages from the installed packages. Use filter_uptodate_packages=
to set it to false to install all packages regardless of their status
Source
# File lib/autoproj/os_package_installer.rb, line 424 def install( osdep_packages, all: nil, install_only: false, run_package_managers_without_packages: false, **options ) setup_package_managers(**options) partitioned_packages = resolve_and_partition_osdep_packages(osdep_packages, all) # Install OS packages first, as the other package handlers might # depend on OS packages if (os_packages = partitioned_packages.delete(os_package_manager)) install_manager_packages( os_package_manager, os_packages, install_only: install_only, run_package_managers_without_packages: run_package_managers_without_packages ) end partitioned_packages.each do |manager, package_list| install_manager_packages( manager, package_list, install_only: install_only, run_package_managers_without_packages: run_package_managers_without_packages ) end end
Requests the installation of the given set of packages
Source
# File lib/autoproj/os_package_installer.rb, line 452 def install_manager_packages(manager, package_list, install_only: false, run_package_managers_without_packages: false) list = package_list.to_set - installed_resolved_packages[manager] if !list.empty? || run_package_managers_without_packages manager.install( list.to_a, filter_uptodate_packages: filter_uptodate_packages?, install_only: install_only ) installed_resolved_packages[manager].merge(list) end end
Source
# File lib/autoproj/os_package_installer.rb, line 67 def os_package_manager unless @os_package_manager name = os_package_resolver.os_package_manager @os_package_manager = package_managers[name] || PackageManagers::UnknownOSManager.new(ws) end @os_package_manager end
Returns the package manager object for the current OS
Source
# File lib/autoproj/os_package_installer.rb, line 224 def osdeps_mode # This has two uses. It caches the value extracted from the # AUTOPROJ_OSDEPS_MODE and/or configuration file. Moreover, it # allows to override the osdeps mode by using # OSPackageInstaller#osdeps_mode= return @osdeps_mode if @osdeps_mode config = ws.config loop do mode = if !config.has_value_for?("osdeps_mode") && (mode_name = ENV["AUTOPROJ_OSDEPS_MODE"]) begin osdeps_mode_string_to_value(mode_name) rescue ArgumentError Autoproj.warn "invalid osdeps mode given through "\ "AUTOPROJ_OSDEPS_MODE (#{mode})" nil end else mode_name = config.get("osdeps_mode") begin osdeps_mode_string_to_value(mode_name) rescue ArgumentError Autoproj.warn "invalid osdeps mode stored "\ "in configuration file" nil end end if mode @osdeps_mode = mode config.set("osdeps_mode", mode_name, true) return mode end # Invalid configuration values. Retry config.reset("osdeps_mode") ENV["AUTOPROJ_OSDEPS_MODE"] = nil end end
Returns the osdeps mode chosen by the user
Source
# File lib/autoproj/os_package_installer.rb, line 219 def osdeps_mode=(value) @osdeps_mode = osdeps_mode_string_to_value(value) end
Override the osdeps mode
Source
# File lib/autoproj/os_package_installer.rb, line 129 def osdeps_mode_option_supported_os(config) long_doc = <<-EOT The software packages that autoproj will have to build may require other prepackaged softwares (a.k.a. OS dependencies) to be installed (RubyGems packages, packages from your operating system/distribution, ...). Autoproj is able to install those automatically for you. Advanced users may want to control this behaviour. Additionally, the installation of some packages require administration rights, which you may not have. This option is meant to allow you to control autoproj's behaviour while handling OS dependencies. * if you say "all", it will install all packages automatically. This requires root access thru 'sudo' * if you say "pip", only the Python packages will be installed. Installing these packages does not require root access. * if you say "gem", only the Ruby packages will be installed. Installing these packages does not require root access. * if you say "os", only the OS-provided packages will be installed. Installing these packages requires root access. * if you say "none", autoproj will not do anything related to the OS dependencies. Finally, you can provide a comma-separated list of pip gem and os. As any configuration value, the mode can be changed anytime by calling autoproj reconfigure Finally, the "autoproj osdeps" command will give you the necessary information about the OS packages that you will need to install manually. So, what do you want ? (all, none or a comma-separated list of: os gem pip) EOT 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] config.declare "osdeps_mode", "string", default: "all", doc: message, lowercase: true end
Source
# File lib/autoproj/os_package_installer.rb, line 92 def osdeps_mode_option_unsupported_os(config) long_doc = <<-EOT The software packages that autoproj will have to build may require other prepackaged softwares (a.k.a. OS dependencies) to be installed (RubyGems packages, packages from your operating system/distribution, ...). Autoproj is usually able to install those automatically, but unfortunately your operating system is not (yet) supported by autoproj's osdeps mechanism, it can only offer you some limited support. Some package handlers are cross-platform, and are therefore supported. However, you will have to install the kind of OS dependencies (so-called OS packages) This option is meant to allow you to control autoproj's behaviour while handling OS dependencies. * if you say "all", all OS-independent packages are going to be installed. * if you say "gem", the RubyGem packages will be installed. * if you say "pip", the Python PIP packages will be installed. * if you say "none", autoproj will not do anything related to the OS dependencies. As any configuration value, the mode can be changed anytime by calling autoproj reconfigure Finally, the "autoproj osdeps" command will give you the necessary information about the OS packages that you will need to install manually. So, what do you want ? (all, none or a comma-separated list of: gem pip) EOT 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] config.declare "osdeps_mode", "string", default: "ruby", doc: message, lowercase: true end
Source
# File lib/autoproj/os_package_installer.rb, line 178 def osdeps_mode_string_to_value(string) user_modes = string.to_s.downcase.split(",") modes = [] user_modes.each do |str| case str when "all" then modes.concat(%w[os gem pip]) when "ruby" then modes << "gem" when "gem" then modes << "gem" when "pip" then modes << "pip" when "os" then modes << "os" when "none" then # noop else if package_managers.key?(str) modes << str else raise ArgumentError, "#{str} is not a known package handler, known handlers are #{package_managers.keys.sort.join(', ')}" end end end modes end
Source
# File lib/autoproj/os_package_installer.rb, line 309 def pristine(packages, options = Hash.new) install(packages, options.merge(install_only: true)) packages = os_package_resolver.resolve_os_packages(packages) packages = packages.map do |handler_name, list| unless (manager = package_managers[handler_name]) raise ArgumentError, "no package manager called #{handler_name} found" end [manager, list] end _, other_packages = packages.partition { |handler, list| handler == os_package_manager } other_packages.each do |handler, list| handler.pristine(list) if handler.respond_to?(:pristine) end end
Requests that packages that are handled within the autoproj project (i.e. gems) are restored to pristine condition
This is usually called as a rebuild step to make sure that all these packages are updated to whatever required the rebuild
Source
# File lib/autoproj/os_package_installer.rb, line 364 def resolve_and_partition_osdep_packages(osdep_packages, all_osdep_packages = nil) packages = os_package_resolver.resolve_os_packages(osdep_packages) packages = resolve_package_managers_in_mapping(packages) all_packages = os_package_resolver.resolve_os_packages(all_osdep_packages || Array.new) all_packages = resolve_package_managers_in_mapping(all_packages) partitioned_packages = Hash.new package_managers.each do |manager_name, manager| manager_selected = packages.fetch(manager, Set.new).to_set manager_all = all_packages.fetch(manager, Set.new).to_set next if manager_selected.empty? && !manager.call_while_empty? # If the manager is strict, we need to bypass it if we did not # get the complete list of osdep packages if manager.strict? && !all_osdep_packages unless manager_selected.empty? raise InternalError, "requesting to install the osdeps #{partitioned_packages[manager].to_a.sort.join(', ')} through #{manager_name} but the complete list of osdep packages managed by this manager was not provided. This would break the workspace" end next end if manager.strict? manager_packages = manager_all | manager_selected else manager_packages = manager_selected end partitioned_packages[manager] = manager_packages end resolve_managers_dependencies(partitioned_packages) end
@api private
Resolves and partitions osdep packages into the various package managers. The returned hash will have one entry per package manager that has a package, with additional entries for package managers that have an empty list but for which {PackageManagers::Manager#call_while_empty?} returns true
@param [Array<String>] osdep_packages the list of osdeps to install @return [Hash<PackageManagers::Manager,Array<(String, String)>] the
resolved and partitioned osdeps
@raise (see resolve_package_managers_in_mapping
) @raise [InternalError] if all_osdep_packages is not provided (is nil)
and some strict package managers need to be called to handle osdep_packages
Source
# File lib/autoproj/os_package_installer.rb, line 398 def resolve_managers_dependencies(partitioned_packages) partitioned_packages.clone.each do |manager, packages| # Skip if the manager is not being used next if packages&.empty? manager_dependencies = os_package_resolver.resolve_os_packages(manager.os_dependencies) manager_dependencies = resolve_package_managers_in_mapping(manager_dependencies) manager_dependencies.each_key do |nested_manager| deps = manager_dependencies.fetch(nested_manager, Set.new).to_set next if deps.empty? unless partitioned_packages[nested_manager] partitioned_packages[nested_manager] = Set.new enable_recursion = true end partitioned_packages[nested_manager] += deps if enable_recursion partitioned_packages = resolve_managers_dependencies(partitioned_packages) end end end partitioned_packages end
Source
# File lib/autoproj/os_package_installer.rb, line 337 def resolve_package_managers_in_mapping(mapping) resolved = Hash.new mapping.each do |manager_name, package_list| unless (manager = package_managers[manager_name]) raise ArgumentError, "no package manager called #{handler_name} found" end resolved[manager] = package_list end resolved end
@api private
Resolves the package managers from their name in a manager-to-package list mapping.
This is a helper method to resolve the value returned by {OSPackageResolver#resolve_os_packages}
@raise [ArgumentError] if a manager name cannot be resolved
Source
# File lib/autoproj/os_package_installer.rb, line 275 def setup_package_managers(osdeps_mode: self.osdeps_mode) os_package_manager.enabled = false package_managers.each_value do |handler| handler.enabled = false end osdeps_mode.each do |m| if m == "os" os_package_manager.enabled = true elsif (pkg = package_managers[m]) pkg.enabled = true else available = package_managers.keys.map(&:inspect).sort.join(", ") Autoproj.warn "osdep handler #{m.inspect} found in osdep_mode "\ "has no handler, available handlers are #{available}" end end os_package_manager.silent = silent? package_managers.each_value do |v| v.silent = silent? end enabled_handlers = [] enabled_handlers << os_package_manager if os_package_manager.enabled? package_managers.each_value do |v| enabled_handlers << v if v.enabled? end enabled_handlers end
Set up the registered package handlers according to the specified osdeps mode
It enables/disables package handlers based on either the value returned by {#osdeps_mode} or the value passed as option (the latter takes precedence). Moreover, sets the handler’s silent flag using {#silent?}
@option options [Array<String>] the package handlers that should be
enabled. The default value is returned by {#osdeps_mode}
@return [Array<PackageManagers::Manager>] the set of enabled package
managers