autoproj 2.9.0 → 2.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +113 -0
  3. data/.travis.yml +0 -2
  4. data/Gemfile +1 -0
  5. data/README.md +59 -14
  6. data/bin/autoproj_bootstrap +21 -12
  7. data/bin/autoproj_bootstrap.in +2 -2
  8. data/bin/autoproj_install +21 -12
  9. data/bin/autoproj_install.in +2 -2
  10. data/lib/autoproj/aruba_minitest.rb +4 -4
  11. data/lib/autoproj/autobuild_extensions/dsl.rb +91 -70
  12. data/lib/autoproj/autobuild_extensions/package.rb +20 -1
  13. data/lib/autoproj/build_option.rb +24 -7
  14. data/lib/autoproj/cli/base.rb +12 -1
  15. data/lib/autoproj/cli/bootstrap.rb +9 -3
  16. data/lib/autoproj/cli/build.rb +17 -13
  17. data/lib/autoproj/cli/envsh.rb +1 -1
  18. data/lib/autoproj/cli/exec.rb +5 -7
  19. data/lib/autoproj/cli/main.rb +44 -9
  20. data/lib/autoproj/cli/main_test.rb +2 -0
  21. data/lib/autoproj/cli/test.rb +29 -6
  22. data/lib/autoproj/cli/version.rb +52 -0
  23. data/lib/autoproj/cli/versions.rb +4 -1
  24. data/lib/autoproj/cli/watch.rb +2 -1
  25. data/lib/autoproj/configuration.rb +49 -11
  26. data/lib/autoproj/default.osdeps +9 -0
  27. data/lib/autoproj/manifest.rb +6 -6
  28. data/lib/autoproj/ops/build.rb +5 -15
  29. data/lib/autoproj/ops/import.rb +22 -3
  30. data/lib/autoproj/ops/install.rb +19 -10
  31. data/lib/autoproj/ops/main_config_switcher.rb +12 -6
  32. data/lib/autoproj/ops/snapshot.rb +5 -1
  33. data/lib/autoproj/os_package_resolver.rb +245 -209
  34. data/lib/autoproj/package_selection.rb +18 -0
  35. data/lib/autoproj/reporter.rb +45 -31
  36. data/lib/autoproj/test.rb +107 -56
  37. data/lib/autoproj/version.rb +1 -1
  38. data/lib/autoproj/workspace.rb +90 -72
  39. data/shell/completion/amake_bash +1 -0
  40. data/shell/completion/amake_zsh +1 -0
  41. data/shell/completion/autoproj_bash +2 -0
  42. data/shell/completion/autoproj_zsh +2 -0
  43. metadata +5 -3
@@ -162,6 +162,15 @@ pip:
162
162
  freebsd: pip
163
163
  default: ignore # assume pip will be installed by the user
164
164
 
165
+ python:
166
+ arch: python2
167
+ debian,ubuntu: python-dev
168
+ fedora: python-devel
169
+ freebsd: python-devel
170
+ gentoo: dev-lang/python
171
+ opensuse: python-devel
172
+ default: ignore # will be installed manually by the user
173
+
165
174
  sudo:
166
175
  macos-brew: ignore
167
176
  default: sudo
@@ -19,11 +19,11 @@ class Manifest
19
19
 
20
20
  # Loads the manifest file located at +file+ and returns the Manifest
21
21
  # instance that represents it
22
- def self.load(file)
23
- manifest = Manifest.new
22
+ def self.load(file)
23
+ manifest = Manifest.new
24
24
  manifest.load(file)
25
25
  manifest
26
- end
26
+ end
27
27
 
28
28
  # A normalized version of the layout as represented in the manifest file
29
29
  #
@@ -176,7 +176,7 @@ def initialize(ws, os_package_resolver: OSPackageResolver.new)
176
176
  @ws = ws
177
177
  @vcs = VCSDefinition.none
178
178
  @file = nil
179
- @data = Hash.new
179
+ @data = Hash.new
180
180
  @has_layout = false
181
181
  @normalized_layout = Hash.new
182
182
  @packages = Hash.new
@@ -198,7 +198,7 @@ def initialize(ws, os_package_resolver: OSPackageResolver.new)
198
198
 
199
199
  @constant_definitions = Hash.new
200
200
  @package_sets << LocalPackageSet.new(ws)
201
- end
201
+ end
202
202
 
203
203
  # @api private
204
204
  #
@@ -994,7 +994,7 @@ def load_package_manifest(pkg)
994
994
 
995
995
  # Look for the package's manifest.xml, but fallback to a manifest in
996
996
  # the package set if present
997
- if package.use_package_xml?
997
+ if package.use_package_xml? && package.checked_out?
998
998
  manifest_path = File.join(package.srcdir, "package.xml")
999
999
  raise NoPackageXML.new(package.srcdir), "#{package.name} from "\
1000
1000
  "#{package_set.name} has use_package_xml set, but the package has "\
@@ -13,9 +13,9 @@ class Build
13
13
 
14
14
  # @param [String] report_dir the log directory in which to build
15
15
  # the build report. If left to nil, no report will be generated
16
- def initialize(manifest, report_dir: nil)
16
+ def initialize(manifest, report_path: nil)
17
17
  @manifest = manifest
18
- @report_dir = report_dir
18
+ @report_path = report_path
19
19
  end
20
20
 
21
21
  # Triggers a rebuild of all packages
@@ -92,22 +92,12 @@ def build_packages(all_enabled_packages, options = Hash.new)
92
92
  begin
93
93
  Autobuild.apply(all_enabled_packages, "autoproj-build", ['build'], options)
94
94
  ensure
95
- build_report(all_enabled_packages) if @report_dir
95
+ build_report(all_enabled_packages) if @report_path
96
96
  end
97
97
  end
98
98
 
99
- REPORT_BASENAME = "build_report.json"
100
-
101
- # The path to the report file
102
- #
103
- # @return [String,nil] the path, or nil if the report should not
104
- # be generated
105
- def report_path
106
- File.join(@report_dir, REPORT_BASENAME) if @report_dir
107
- end
108
-
109
99
  def build_report(package_list)
110
- FileUtils.mkdir_p @report_dir
100
+ FileUtils.mkdir_p File.dirname(@report_path)
111
101
 
112
102
  packages = package_list.map do |pkg_name|
113
103
  pkg = manifest.find_autobuild_package(pkg_name)
@@ -130,7 +120,7 @@ def build_report(package_list)
130
120
  packages: packages
131
121
  }
132
122
  })
133
- IO.write(report_path, build_report)
123
+ IO.write(@report_path, build_report)
134
124
  end
135
125
  end
136
126
  end
@@ -73,7 +73,7 @@ def import_next_step(pkg, reverse_dependencies)
73
73
  end
74
74
  new_packages
75
75
  end
76
-
76
+
77
77
  def pre_package_import(selection, manifest, pkg, reverse_dependencies)
78
78
  # Try to auto-exclude the package early. If the autobuild file
79
79
  # contained some information that allows us to exclude it now,
@@ -133,12 +133,30 @@ def install_vcs_packages_for(*packages, **osdeps_options)
133
133
  vcs_to_install
134
134
  end
135
135
 
136
+ # Install the internal dependencies for the given packages
137
+ #
138
+ # @param [Hash] osdeps_options the options that will be passed to
139
+ # {Workspace#install_os_packages}
140
+ # @return [Set] the set of installed OS packages
141
+ def install_internal_dependencies_for(*packages, **osdeps_options)
142
+ packages_to_install = packages.map do |pkg|
143
+ pkg.autobuild.internal_dependencies
144
+ end.flatten.uniq
145
+ return if packages_to_install.empty?
146
+
147
+ # This assumes that the internal dependencies do not depend on a
148
+ # 'strict' package mangers such as e.g. BundlerManager and that
149
+ # the package manager itself does not have any dependencies
150
+ ws.install_os_packages(packages_to_install, all: nil, **osdeps_options)
151
+ packages_to_install
152
+ end
153
+
136
154
  # @api private
137
155
  #
138
156
  # Queue the work necessary to import the given package, making sure
139
157
  # that the execution results end up in a given queue
140
158
  #
141
- # @param executor the future executor
159
+ # @param executor the future executor
142
160
  # @param [Queue] completion_queue the queue where the completion
143
161
  # results should be pushed, as a (package, time, result,
144
162
  # error_reason) tuple
@@ -331,7 +349,7 @@ def import_selected_packages(selection,
331
349
  executor.wait_for_termination
332
350
  end
333
351
  end
334
-
352
+
335
353
  def finalize_package_load(processed_packages, auto_exclude: auto_exclude?)
336
354
  manifest = ws.manifest
337
355
 
@@ -405,6 +423,7 @@ def import_packages(selection,
405
423
  raise failures.first
406
424
  end
407
425
 
426
+ install_internal_dependencies_for(*all_processed_packages)
408
427
  finalize_package_load(all_processed_packages, auto_exclude: auto_exclude)
409
428
 
410
429
  all_enabled_osdeps = selection.each_osdep_package_name.to_set
@@ -229,6 +229,9 @@ def parse_options(args = ARGV)
229
229
  opt.on '--skip-stage2', 'do not run the stage2 install' do
230
230
  @skip_stage2 = true
231
231
  end
232
+ opt.on '--debug', 'Run in debug mode' do
233
+ @autoproj_options << '--debug'
234
+ end
232
235
  opt.on '--gem-source=URL', String, "use this source for RubyGems "\
233
236
  "instead of rubygems.org" do |url|
234
237
  @gem_source = url
@@ -265,19 +268,25 @@ def parse_options(args = ARGV)
265
268
  end
266
269
  opt.on '--[no-]color', 'do not use colored output (enabled by "\
267
270
  "default if the terminal supports it)' do |color|
268
- if color then autoproj_options << "--color"
269
- else autoproj_options << '--no-color'
271
+ if color then @autoproj_options << "--color"
272
+ else @autoproj_options << '--no-color'
270
273
  end
271
274
  end
272
275
  opt.on '--[no-]progress', 'do not use progress output (enabled by "\
273
- "default if the terminal supports it)' do |color|
274
- if color then autoproj_options << "--progress"
275
- else autoproj_options << '--no-progress'
276
+ "default if the terminal supports it)' do |progress|
277
+ if progress then @autoproj_options << "--progress"
278
+ else @autoproj_options << '--no-progress'
279
+ end
280
+ end
281
+ opt.on '--[no-]interactive', 'if non-interactive, use default "\
282
+ "answer for questions' do |flag|
283
+ if flag then @autoproj_options << "--interactive"
284
+ else @autoproj_options << "--no-interactive"
276
285
  end
277
286
  end
278
287
  end
279
288
  args = options.parse(ARGV)
280
- autoproj_options + args
289
+ @autoproj_options + args
281
290
  end
282
291
 
283
292
  def find_bundler(gem_program)
@@ -667,7 +676,7 @@ def autoproj_path
667
676
 
668
677
  def run_autoproj(*args)
669
678
  system env_for_child.merge('BUNDLE_GEMFILE' => autoproj_gemfile_path),
670
- Gem.ruby, autoproj_path, *args, *autoproj_options
679
+ Gem.ruby, autoproj_path, *args, *@autoproj_options
671
680
  end
672
681
 
673
682
  def v1_workspace?
@@ -691,7 +700,7 @@ def call_stage2
691
700
  clean_env = env_for_child
692
701
  stage2_vars = clean_env.map { |k, v| "#{k}=#{v}" }
693
702
  puts "starting the newly installed autoproj for stage2 install"
694
- if !run_autoproj('install-stage2', root_dir, *stage2_vars)
703
+ if !run_autoproj('install-stage2', root_dir, *stage2_vars, *@autoproj_options)
695
704
  raise "failed to execute autoproj install-stage2"
696
705
  end
697
706
  end
@@ -701,7 +710,7 @@ def stage2(*vars)
701
710
  puts "saving temporary env.sh and .autoproj/env.sh"
702
711
  save_env_sh(*vars)
703
712
  puts "running 'autoproj envsh' to generate a proper env.sh"
704
- if !system(Gem.ruby, autoproj_path, 'envsh', *autoproj_options)
713
+ if !system(Gem.ruby, autoproj_path, 'envsh', *@autoproj_options)
705
714
  STDERR.puts "failed to run autoproj envsh on the newly installed "\
706
715
  "autoproj (#{autoproj_path})"
707
716
  exit 1
@@ -709,7 +718,7 @@ def stage2(*vars)
709
718
  # This is really needed on an existing install to install the
710
719
  # gems that were present in the v1 layout
711
720
  puts "running 'autoproj osdeps' to re-install missing gems"
712
- if !system(Gem.ruby, autoproj_path, 'osdeps')
721
+ if !system(Gem.ruby, autoproj_path, 'osdeps', *@autoproj_options)
713
722
  STDERR.puts "failed to run autoproj osdeps on the newly installed "\
714
723
  "autoproj (#{autoproj_path})"
715
724
  exit 1
@@ -16,16 +16,20 @@ def initialize(ws)
16
16
  EXPECTED_ROOT_ENTRIES = [".", "..", "autoproj_bootstrap",
17
17
  ".autoproj", "bootstrap.sh", ENV_FILENAME].to_set
18
18
 
19
+
20
+ def check_root_dir_empty?
21
+ (ENV['AUTOPROJ_NONINTERACTIVE'] != '1') &&
22
+ (ENV['AUTOPROJ_BOOTSTRAP_IGNORE_NONEMPTY_DIR'] != '1')
23
+ end
24
+
19
25
  # Verifies that {#root_dir} contains only expected entries, to make
20
26
  # sure that the user bootstraps into a new directory
21
27
  #
22
28
  # If the environment variable AUTOPROJ_BOOTSTRAP_IGNORE_NONEMPTY_DIR
23
29
  # is set to 1, the check is skipped
24
30
  def check_root_dir_empty
25
- return if ENV['AUTOPROJ_BOOTSTRAP_IGNORE_NONEMPTY_DIR'] == '1'
26
-
27
31
  require 'set'
28
- curdir_entries = Dir.entries(ws.root_dir).map { |p| File.basename(p) }.to_set -
32
+ curdir_entries = Dir.entries(ws.root_dir).map { |p| File.basename(p) }.to_set -
29
33
  EXPECTED_ROOT_ENTRIES
30
34
  return if curdir_entries.empty?
31
35
 
@@ -73,8 +77,10 @@ def validate_autoproj_current_root(reuse)
73
77
 
74
78
  MAIN_CONFIGURATION_TEMPLATE = File.expand_path(File.join("..", "..", "..", "samples", 'autoproj'), File.dirname(__FILE__))
75
79
 
76
- def bootstrap(buildconf_info, reuse: Array.new)
77
- check_root_dir_empty
80
+ def bootstrap(buildconf_info,
81
+ check_root_dir_empty: check_root_dir_empty?,
82
+ reuse: Array.new)
83
+ self.check_root_dir_empty if check_root_dir_empty
78
84
  validate_autoproj_current_root(reuse)
79
85
 
80
86
  ws.config.validate_ruby_executable
@@ -179,7 +185,7 @@ def do_switch_config(delete_current, type, url, *options)
179
185
  backup_name = "#{backup_base_name}-#{index}.bak"
180
186
  index += 1
181
187
  end
182
-
188
+
183
189
  FileUtils.mv config_dir, backup_name
184
190
  end
185
191
 
@@ -117,7 +117,7 @@ def error_or_warn(package, error)
117
117
  end
118
118
  end
119
119
 
120
- def snapshot_packages(packages, target_dir = nil, only_local: true)
120
+ def snapshot_packages(packages, target_dir = nil, only_local: true, fingerprint: false)
121
121
  result = Array.new
122
122
  packages.each do |package_name|
123
123
  package = manifest.find_package_definition(package_name)
@@ -140,6 +140,10 @@ def snapshot_packages(packages, target_dir = nil, only_local: true)
140
140
  next
141
141
  end
142
142
 
143
+ if fingerprint
144
+ vcs_info['fingerprint'] = package.autobuild.fingerprint
145
+ end
146
+
143
147
  if vcs_info
144
148
  result << Hash[package_name, vcs_info]
145
149
  else
@@ -5,31 +5,35 @@ module Autoproj
5
5
  # Manager for packages provided by external package managers
6
6
  class OSPackageResolver
7
7
  def self.load(file, suffixes: [], **options)
8
- if !File.file?(file)
9
- raise ArgumentError, "no such file or directory #{file}"
10
- end
8
+ unless File.file?(file)
9
+ raise ArgumentError, "no such file or directory #{file}"
10
+ end
11
+
12
+ candidates = [file]
13
+ candidates.concat(suffixes.map { |s| "#{file}-#{s}" })
11
14
 
12
- candidates = [file]
13
- candidates.concat(suffixes.map { |s| "#{file}-#{s}" })
15
+ error_t =
16
+ if defined? Psych::SyntaxError
17
+ [ArgumentError, Psych::SyntaxError]
18
+ else ArgumentError
19
+ end
14
20
 
15
- error_t = if defined? Psych::SyntaxError then [ArgumentError, Psych::SyntaxError]
16
- else ArgumentError
17
- end
21
+ result = new(**options)
22
+ candidates.each do |file_candidate|
23
+ next unless File.file?(file_candidate)
18
24
 
19
- result = new(**options)
20
- candidates.each do |file_candidate|
21
- next if !File.file?(file_candidate)
22
25
  file_candidate = File.expand_path(file_candidate)
23
26
  begin
24
- data = YAML.load(File.read(file_candidate)) || Hash.new
27
+ data = YAML.safe_load(File.read(file_candidate)) || Hash.new
25
28
  verify_definitions(data)
26
29
  rescue *error_t => e
27
- raise ConfigError.new, "error in #{file_candidate}: #{e.message}", e.backtrace
30
+ raise ConfigError.new, "error in #{file_candidate}: "\
31
+ "#{e.message}", e.backtrace
28
32
  end
29
33
 
30
34
  result.merge(new(data, file_candidate, **options))
31
- end
32
- result
35
+ end
36
+ result
33
37
  end
34
38
 
35
39
  # The underlying workspace
@@ -43,11 +47,12 @@ def self.autodetect_ruby_program
43
47
  ruby_executable
44
48
  end
45
49
 
46
- AUTOPROJ_OSDEPS = File.join(File.expand_path(File.dirname(__FILE__)), 'default.osdeps')
50
+ AUTOPROJ_OSDEPS = File.join(__dir__, 'default.osdeps')
47
51
  def self.load_default
48
52
  file = ENV['AUTOPROJ_DEFAULT_OSDEPS'] || AUTOPROJ_OSDEPS
49
- if !File.file?(file)
50
- Autoproj.warn "#{file} (from AUTOPROJ_DEFAULT_OSDEPS) is not a file, falling back to #{AUTOPROJ_OSDEPS}"
53
+ unless File.file?(file)
54
+ Autoproj.warn "#{file} (from AUTOPROJ_DEFAULT_OSDEPS) is not a file, "\
55
+ "falling back to #{AUTOPROJ_OSDEPS}"
51
56
  file = AUTOPROJ_OSDEPS
52
57
  end
53
58
  load(file)
@@ -58,7 +63,7 @@ def load_default
58
63
  end
59
64
 
60
65
  PACKAGE_MANAGERS = OSPackageInstaller::PACKAGE_MANAGERS.keys
61
-
66
+
62
67
  # Mapping from OS name to package manager name
63
68
  #
64
69
  # Package handlers and OSes MUST have different names. The former are
@@ -71,15 +76,15 @@ def load_default
71
76
  #
72
77
  # we need to be able to separate between OS and package manager names.
73
78
  OS_PACKAGE_MANAGERS = {
74
- 'debian' => 'apt-dpkg',
75
- 'gentoo' => 'emerge',
76
- 'arch' => 'pacman',
77
- 'fedora' => 'yum',
79
+ 'debian' => 'apt-dpkg',
80
+ 'gentoo' => 'emerge',
81
+ 'arch' => 'pacman',
82
+ 'fedora' => 'yum',
78
83
  'macos-port' => 'macports',
79
84
  'macos-brew' => 'brew',
80
- 'opensuse' => 'zypper',
81
- 'freebsd' => 'pkg'
82
- }
85
+ 'opensuse' => 'zypper',
86
+ 'freebsd' => 'pkg'
87
+ }.freeze
83
88
 
84
89
  # The information contained in the OSdeps files, as a hash
85
90
  attr_reader :definitions
@@ -93,16 +98,20 @@ def load_default
93
98
  # Controls whether the package resolver will prefer installing
94
99
  # OS-independent packages (such as e.g. Gems) over their OS-provided
95
100
  # equivalent (e.g. the packaged version of a gem)
96
- def prefer_indep_over_os_packages?; !!@prefer_indep_over_os_packages end
101
+ def prefer_indep_over_os_packages?
102
+ @prefer_indep_over_os_packages
103
+ end
97
104
  # (see prefer_indep_over_os_packages?)
98
- def prefer_indep_over_os_packages=(flag); @prefer_indep_over_os_packages = flag end
105
+ attr_writer :prefer_indep_over_os_packages
99
106
  # Cached results of {#resolve_package}
100
107
  attr_reader :resolve_package_cache
101
108
 
102
109
  # Use to override the autodetected OS-specific package handler
103
110
  def os_package_manager=(manager_name)
104
111
  if manager_name && !package_managers.include?(manager_name)
105
- raise ArgumentError, "#{manager_name} is not a known package manager, known managers are #{package_managers.to_a.sort.join(", ")}"
112
+ raise ArgumentError, "#{manager_name} is not a known "\
113
+ "package manager, known managers are "\
114
+ "#{package_managers.to_a.sort.join(', ')}"
106
115
  end
107
116
  @os_package_manager = manager_name
108
117
  end
@@ -111,13 +120,12 @@ def os_package_manager=(manager_name)
111
120
  #
112
121
  # @return [String]
113
122
  def os_package_manager
114
- if !@os_package_manager
115
- os_names, _ = operating_system
123
+ unless @os_package_manager
124
+ os_names, = operating_system
116
125
  os_name = os_names.find { |name| OS_PACKAGE_MANAGERS[name] }
117
- @os_package_manager = OS_PACKAGE_MANAGERS[os_name] ||
118
- 'unknown'
126
+ @os_package_manager = OS_PACKAGE_MANAGERS[os_name] || 'unknown'
119
127
  end
120
- return @os_package_manager
128
+ @os_package_manager
121
129
  end
122
130
 
123
131
  # Returns the set of known package managers
@@ -143,7 +151,7 @@ def initialize(defs = Hash.new, file = nil,
143
151
  @prefer_indep_over_os_packages = false
144
152
  @aliases = Hash.new
145
153
 
146
- @sources = Hash.new
154
+ @sources = Hash.new
147
155
  @installed_packages = Set.new
148
156
  @operating_system = operating_system
149
157
  @supported_operating_system = nil
@@ -195,57 +203,58 @@ def invalidate_resolve_package_cache
195
203
  # takes precedence
196
204
  def merge(info, suffixes: [])
197
205
  @definitions = definitions.merge(info.definitions) do |h, v1, v2|
198
- if v1 != v2
199
- warn_about_merge_collisions(info, suffixes, h, v1, v2)
200
- end
206
+ warn_about_merge_collisions(info, suffixes, h, v1, v2) if v1 != v2
201
207
  v2
202
208
  end
203
209
  invalidate_resolve_package_cache
204
210
 
205
211
  @sources = sources.merge(info.sources)
206
- @all_definitions = all_definitions.merge(info.all_definitions) do |package_name, all_defs, new_all_defs|
207
- all_defs = all_defs.dup
208
- new_all_defs = new_all_defs.dup
209
- new_all_defs.delete_if do |files, data|
210
- if entry = all_defs.find { |_, d| d == data }
211
- entry[0] |= files
212
+ @all_definitions = all_definitions.
213
+ merge(info.all_definitions) do |_package_name, all_defs, new_all_defs|
214
+ all_defs = all_defs.dup
215
+ new_all_defs = new_all_defs.dup
216
+ new_all_defs.delete_if do |files, data|
217
+ if (entry = all_defs.find { |_, d| d == data })
218
+ entry[0] |= files
219
+ end
212
220
  end
221
+ all_defs.concat(new_all_defs)
213
222
  end
214
- all_defs.concat(new_all_defs)
215
- end
216
223
  end
217
224
 
218
225
  # @api private
219
226
  #
220
227
  # Warn about a collision (override) detected during #merge
221
- def warn_about_merge_collisions(merged_info, suffixes, key, old_value, new_value)
228
+ def warn_about_merge_collisions(merged_info, suffixes, key,
229
+ _old_value, _new_value)
222
230
  old = source_of(key)
223
231
  new = merged_info.source_of(key)
224
232
 
225
- if suffixes.any? { |s| "#{old}#{s}" == new }
226
- return
227
- end
233
+ return if suffixes.any? { |s| new == "#{old}#{s}" }
228
234
 
229
235
  # Warn if the new osdep definition resolves to a different
230
236
  # set of packages than the old one
231
- old_resolved = resolve_package(key, resolve_recursive: false).inject(Hash.new) do |osdep_h, (handler, status, list)|
232
- osdep_h[handler] = [status, list.dup]
233
- osdep_h
234
- end
235
- new_resolved = merged_info.resolve_package(key, resolve_recursive: false).inject(Hash.new) do |osdep_h, (handler, status, list)|
236
- osdep_h[handler] = [status, list.dup]
237
- osdep_h
238
- end
237
+ old_resolved = resolve_package(key, resolve_recursive: false).
238
+ each_with_object(Hash.new) do |(handler, status, list), osdep_h|
239
+ osdep_h[handler] = [status, list.dup]
240
+ end
241
+ new_resolved = merged_info.resolve_package(key, resolve_recursive: false).
242
+ each_with_object(Hash.new) do |(handler, status, list), osdep_h|
243
+ osdep_h[handler] = [status, list.dup]
244
+ end
239
245
  if old_resolved != new_resolved
240
- Autoproj.warn "osdeps definition for #{key}, previously defined in #{old} overridden by #{new}:"
246
+ Autoproj.warn "osdeps definition for #{key}, "\
247
+ "previously defined in #{old} overridden by #{new}:"
241
248
  first = true
242
249
  old_resolved.each do |handler, (_, packages)|
243
- Autoproj.warn " #{first ? 'resp. ' : ' '}#{handler}: #{packages.map(&:to_s).join(", ")}"
250
+ Autoproj.warn " #{first ? 'resp. ' : ' '}#{handler}: "\
251
+ "#{packages.map(&:to_s).join(', ')}"
244
252
  first = false
245
253
  end
246
254
  first = true
247
255
  new_resolved.each do |handler, (_, packages)|
248
- Autoproj.warn " #{first ? 'and ' : ' '}#{handler}: #{packages.map(&:to_s).join(", ")}"
256
+ Autoproj.warn " #{first ? 'and ' : ' '}#{handler}: "\
257
+ "#{packages.map(&:to_s).join(', ')}"
249
258
  first = false
250
259
  end
251
260
  end
@@ -255,25 +264,27 @@ def warn_about_merge_collisions(merged_info, suffixes, key, old_value, new_value
255
264
  def self.verify_definitions(hash, path = [])
256
265
  hash.each do |key, value|
257
266
  if value && !key.kind_of?(String)
258
- raise ArgumentError, "invalid osdeps definition: found an #{key.class} as a key in #{path.join("/")}. Don't forget to put quotes around numbers"
267
+ raise ArgumentError, "invalid osdeps definition: "\
268
+ "found an #{key.class} as a key in #{path.join('/')}. "\
269
+ "Don't forget to put quotes around numbers"
259
270
  elsif !value && (key.kind_of?(Hash) || key.kind_of?(Array))
260
271
  verify_definitions(key)
261
272
  end
262
- next if !value
273
+ next unless value
263
274
 
264
275
  if value.kind_of?(Array) || value.kind_of?(Hash)
265
276
  verify_definitions(value, (path + [key]))
266
- else
267
- if !value.kind_of?(String)
268
- raise ArgumentError, "invalid osdeps definition: found an #{value.class} as a value in #{path.join("/")}. Don't forget to put quotes around numbers"
269
- end
277
+ elsif !value.kind_of?(String)
278
+ raise ArgumentError, "invalid osdeps definition: "\
279
+ "found an #{value.class} as a value in #{path.join('/')}. "\
280
+ "Don't forget to put quotes around numbers"
270
281
  end
271
282
  end
272
283
  end
273
284
 
274
285
  # Whether the operating system could be autodetected successfully
275
286
  def known_operating_system?
276
- os_names, _ = operating_system
287
+ os_names, = operating_system
277
288
  !os_names.empty?
278
289
  end
279
290
 
@@ -283,24 +294,20 @@ def supported_operating_system?
283
294
  if @supported_operating_system.nil?
284
295
  @supported_operating_system = (os_package_manager != 'unknown')
285
296
  end
286
- return @supported_operating_system
297
+ @supported_operating_system
287
298
  end
288
299
 
289
300
  def self.guess_operating_system
290
301
  if File.exist?('/etc/debian_version')
291
302
  versions = [File.read('/etc/debian_version').strip]
292
- if versions.first =~ /sid/
293
- versions = ["unstable", "sid"]
294
- end
303
+ versions = %w[unstable sid] if versions.first =~ /sid/
295
304
  [['debian'], versions]
296
305
  elsif File.exist?('/etc/redhat-release')
297
306
  release_string = File.read('/etc/redhat-release').strip
298
307
  release_string =~ /(.*) release ([\d.]+)/
299
308
  name = $1.downcase
300
309
  version = $2
301
- if name =~ /Red Hat Entreprise/
302
- name = 'rhel'
303
- end
310
+ name = 'rhel' if name =~ /Red Hat Entreprise/
304
311
  [[name], [version]]
305
312
  elsif File.exist?('/etc/gentoo-release')
306
313
  release_string = File.read('/etc/gentoo-release').strip
@@ -309,19 +316,19 @@ def self.guess_operating_system
309
316
  [['gentoo'], [version]]
310
317
  elsif File.exist?('/etc/arch-release')
311
318
  [['arch'], []]
312
- elsif Autobuild.macos?
313
- version=`sw_vers | head -2 | tail -1`.split(":")[1]
319
+ elsif Autobuild.macos?
320
+ version = `sw_vers | head -2 | tail -1`.split(":")[1]
314
321
  manager =
315
- if ENV['AUTOPROJ_MACOSX_PACKAGE_MANAGER']
316
- ENV['AUTOPROJ_MACOSX_PACKAGE_MANAGER']
317
- else 'macos-brew'
318
- end
319
- if !OS_PACKAGE_MANAGERS.has_key?(manager)
322
+ ENV['AUTOPROJ_MACOSX_PACKAGE_MANAGER'] ||
323
+ 'macos-brew'
324
+ unless OS_PACKAGE_MANAGERS.key?(manager)
320
325
  known_managers = OS_PACKAGE_MANAGERS.keys.grep(/^macos/)
321
- raise ArgumentError, "#{manager} is not a known MacOSX package manager. Known package managers are #{known_managers.join(", ")}"
326
+ raise ArgumentError, "#{manager} is not a known MacOSX "\
327
+ "package manager. Known package managers are "\
328
+ "#{known_managers.join(', ')}"
322
329
  end
323
330
 
324
- managers =
331
+ managers =
325
332
  if manager == 'macos-port'
326
333
  [manager, 'port']
327
334
  else [manager]
@@ -331,12 +338,12 @@ def self.guess_operating_system
331
338
  [['windows'], []]
332
339
  elsif File.exist?('/etc/SuSE-release')
333
340
  version = File.read('/etc/SuSE-release').strip
334
- version =~/.*VERSION\s+=\s+([^\s]+)/
341
+ version =~ /.*VERSION\s+=\s+([^\s]+)/
335
342
  version = $1
336
343
  [['opensuse'], [version.strip]]
337
- elsif Autobuild.freebsd?
338
- version = `uname -r`.strip.split("-")[0]
339
- [['freebsd'],[version]]
344
+ elsif Autobuild.freebsd?
345
+ version = `uname -r`.strip.split("-")[0]
346
+ [['freebsd'], [version]]
340
347
  end
341
348
  end
342
349
 
@@ -349,21 +356,17 @@ def self.ensure_derivatives_refer_to_their_parents(names)
349
356
  '/etc/arch-release' => 'arch',
350
357
  '/etc/SuSE-release' => 'opensuse']
351
358
  version_files.each do |file, name|
352
- if File.exist?(file) && !names.include?(name)
353
- names << name
354
- end
359
+ names << name if File.exist?(file) && !names.include?(name)
355
360
  end
356
361
  names
357
362
  end
358
-
363
+
359
364
  def self.normalize_os_representation(names, versions)
360
365
  # Normalize the names to lowercase
361
366
  names = names.map(&:downcase)
362
367
  versions = versions.map(&:downcase)
363
- if !versions.include?('default')
364
- versions += ['default']
365
- end
366
- return names, versions
368
+ versions += ['default'] unless versions.include?('default')
369
+ [names, versions]
367
370
  end
368
371
 
369
372
  # The operating system self is targetting
@@ -392,20 +395,18 @@ def operating_system=(values)
392
395
  #
393
396
  # Examples: ['debian', ['sid', 'unstable']] or ['ubuntu', ['lucid lynx', '10.04']]
394
397
  def self.autodetect_operating_system
395
- if user_os = ENV['AUTOPROJ_OS']
398
+ if (user_os = ENV['AUTOPROJ_OS'])
396
399
  if user_os.empty?
397
400
  return false
398
401
  else
399
402
  names, versions = user_os.split(':')
400
- return normalize_os_representation(names.split(','), versions.split(','))
403
+ return normalize_os_representation(
404
+ names.split(','), versions.split(','))
401
405
  end
402
406
  end
403
407
 
404
408
  names, versions = os_from_os_release
405
-
406
- if !names
407
- names, versions = guess_operating_system
408
- end
409
+ names, versions = guess_operating_system unless names
409
410
 
410
411
  # on Debian, they refuse to put enough information to detect
411
412
  # 'unstable' reliably. So, we use the heuristic method for it
@@ -416,21 +417,19 @@ def self.autodetect_operating_system
416
417
  # phase...
417
418
  if File.exist?('/etc/debian_version')
418
419
  debian_versions = [File.read('/etc/debian_version').strip]
419
- if debian_versions.first =~ /sid/
420
- versions = ["unstable", "sid"]
421
- end
420
+ versions = %w[unstable sid] if debian_versions.first =~ /sid/
422
421
  end
423
422
  # otherwise "versions" contains the result it previously had
424
423
  end
425
- return if !names
424
+ return unless names
426
425
 
427
426
  names = ensure_derivatives_refer_to_their_parents(names)
428
427
  names, versions = normalize_os_representation(names, versions)
429
- return [names, versions]
428
+ [names, versions]
430
429
  end
431
430
 
432
431
  def self.os_from_os_release(filename = '/etc/os-release')
433
- return if !File.exist?(filename)
432
+ return unless File.exist?(filename)
434
433
 
435
434
  fields = Hash.new
436
435
  File.readlines(filename).each do |line|
@@ -438,7 +437,8 @@ def self.os_from_os_release(filename = '/etc/os-release')
438
437
  if line.strip =~ /^(\w+)=(?:["'])?([^"']+)(?:["'])?$/
439
438
  fields[$1] = $2
440
439
  elsif !line.empty?
441
- Autoproj.warn "could not parse line '#{line.inspect}' in /etc/os-release"
440
+ Autoproj.warn "could not parse line '#{line.inspect}' "\
441
+ "in /etc/os-release"
442
442
  end
443
443
  end
444
444
 
@@ -448,19 +448,17 @@ def self.os_from_os_release(filename = '/etc/os-release')
448
448
  versions << fields['VERSION_ID']
449
449
  version = fields['VERSION'] || ''
450
450
  versions.concat(version.gsub(/[^\w.]/, ' ').split(' '))
451
- return names.compact.uniq, versions.compact.uniq
451
+ [names.compact.uniq, versions.compact.uniq]
452
452
  end
453
453
 
454
454
  def self.os_from_lsb
455
- if !Autobuild.find_in_path('lsb_release')
456
- return
457
- end
455
+ return unless Autobuild.find_in_path('lsb_release')
458
456
 
459
457
  distributor = [`lsb_release -i -s`.strip.downcase]
460
458
  codename = `lsb_release -c -s`.strip.downcase
461
459
  version = `lsb_release -r -s`.strip.downcase
462
460
 
463
- return [distributor, [codename, version]]
461
+ [distributor, [codename, version]]
464
462
  end
465
463
 
466
464
  class InvalidRecursiveStatement < Autobuild::Exception; end
@@ -471,8 +469,8 @@ class InvalidRecursiveStatement < Autobuild::Exception; end
471
469
  # returns an array contain the path starting with name and
472
470
  # ending at the resolved name
473
471
  def resolve_name(name)
474
- path = [ name ]
475
- while aliases.has_key?(name)
472
+ path = [name]
473
+ while aliases.key?(name)
476
474
  name = aliases[name]
477
475
  path << name
478
476
  end
@@ -482,7 +480,9 @@ def resolve_name(name)
482
480
  # Null object class that is used to mark recursive resolution when
483
481
  # calling {#resolve_package} with resolve_recursive set to false
484
482
  class OSDepRecursiveResolver
485
- def self.to_s; 'osdep' end
483
+ def self.to_s
484
+ 'osdep'.freeze
485
+ end
486
486
  end
487
487
 
488
488
  # Return the list of packages that should be installed for +name+
@@ -503,17 +503,13 @@ def self.to_s; 'osdep' end
503
503
  # name and version. The package list might be empty even if status ==
504
504
  # FOUND_PACKAGES, for instance if the ignore keyword is used.
505
505
  def resolve_package(name, resolve_recursive: true)
506
- if resolve_package_cache.has_key?(name)
507
- return resolve_package_cache[name]
508
- end
506
+ return resolve_package_cache[name] if resolve_package_cache.key?(name)
509
507
 
510
508
  path = resolve_name(name)
511
509
  name = path.last
512
510
 
513
511
  dep_def = definitions[name]
514
- if !dep_def
515
- return (resolve_package_cache[name] = nil)
516
- end
512
+ return (resolve_package_cache[name] = nil) unless dep_def
517
513
 
518
514
  os_names, os_versions = operating_system
519
515
 
@@ -534,27 +530,28 @@ def resolve_package(name, resolve_recursive: true)
534
530
  end
535
531
 
536
532
  result = []
537
- found, pkg = partition_osdep_entry(name, dep_def, nil,
538
- (package_managers - [os_package_manager]), os_names, os_versions)
539
- if found
540
- result << [os_package_manager, found, pkg]
541
- end
533
+ found, pkg = partition_osdep_entry(
534
+ name, dep_def, nil,
535
+ (package_managers - [os_package_manager]), os_names, os_versions)
536
+ result << [os_package_manager, found, pkg] if found
542
537
 
543
538
  package_managers.each do |handler|
544
- found, pkg = partition_osdep_entry(name, dep_def, [handler], [], os_names, os_versions)
545
- if found
546
- result << [handler, found, pkg]
547
- end
539
+ found, pkg = partition_osdep_entry(
540
+ name, dep_def, [handler], [], os_names, os_versions)
541
+ result << [handler, found, pkg] if found
548
542
  end
549
543
 
550
544
  # Recursive resolutions
551
- found, pkg = partition_osdep_entry(name, dep_def, ['osdep'], [], os_names, os_versions)
545
+ found, pkg = partition_osdep_entry(
546
+ name, dep_def, ['osdep'], [], os_names, os_versions)
552
547
  if found
553
548
  if resolve_recursive
554
549
  pkg.each do |pkg_name|
555
550
  resolved = resolve_package(pkg_name)
556
- if !resolved
557
- raise InvalidRecursiveStatement, "the '#{name}' osdep refers to another osdep, '#{pkg_name}', which does not seem to exist"
551
+ unless resolved
552
+ raise InvalidRecursiveStatement, "the '#{name}' osdep "\
553
+ "refers to another osdep, '#{pkg_name}', which "\
554
+ "does not seem to exist"
558
555
  end
559
556
  result.concat(resolved)
560
557
  end
@@ -641,66 +638,20 @@ def partition_osdep_entry(osdep_name, dep_def, handler_names, excluded, *keys)
641
638
  found_keys = Hash.new
642
639
  Array(dep_def).each do |names, values|
643
640
  if !values
644
- # Raw array of packages. Possible only if we are not at toplevel
645
- # (i.e. if we already have a handler)
646
- if names == 'ignore'
647
- found = true if !handler_names
648
- elsif names == 'nonexistent'
649
- nonexistent = true if !handler_names
650
- elsif !handler_names && names.kind_of?(Array)
651
- result.concat(result)
652
- found = true
653
- elsif names.respond_to?(:to_str)
654
- if excluded.include?(names)
655
- elsif handler_names && handler_names.include?(names)
656
- result << osdep_name
657
- found = true
658
- elsif !handler_names
659
- result << names
660
- found = true
661
- end
662
- elsif names.respond_to?(:to_hash)
663
- rec_found, rec_result = partition_osdep_entry(osdep_name, names, handler_names, excluded, keys, *additional_keys)
664
- if rec_found == FOUND_NONEXISTENT then nonexistent = true
665
- elsif rec_found == FOUND_PACKAGES then found = true
666
- end
667
- result.concat(rec_result)
668
- end
641
+ entry_found, entry_nonexistent, entry_names =
642
+ partition_osdep_raw_array_entry(names, osdep_name,
643
+ handler_names, excluded, keys, additional_keys)
669
644
  else
670
- if names.respond_to?(:to_str) # names could be an array already
671
- names = names.split(',')
672
- end
673
-
674
- if handler_names
675
- if matching_name = handler_names.find { |k| names.any? { |name_tag| k == name_tag.downcase } }
676
- rec_found, rec_result = partition_osdep_entry(osdep_name, values, nil, excluded, keys, *additional_keys)
677
- if rec_found == FOUND_NONEXISTENT then nonexistent = true
678
- elsif rec_found == FOUND_PACKAGES then found = true
679
- end
680
- result.concat(rec_result)
681
- end
682
- end
683
-
684
- matching_name = keys.find { |k| names.any? { |name_tag| k == name_tag.downcase } }
685
- if matching_name
686
- rec_found, rec_result = partition_osdep_entry(osdep_name, values, handler_names, excluded, *additional_keys)
687
- # We only consider the first highest-priority entry,
688
- # regardless of whether it has some packages for us or
689
- # not
690
- idx = keys.index(matching_name)
691
- if !rec_found
692
- if !found_keys.has_key?(idx)
693
- found_keys[idx] = nil
694
- end
695
- else
696
- found_keys[idx] ||= [0, []]
697
- found_keys[idx][0] += rec_found
698
- found_keys[idx][1].concat(rec_result)
699
- end
700
- end
645
+ entry_found, entry_nonexistent, entry_names =
646
+ partition_osdep_map_entry(names, values, osdep_name,
647
+ handler_names, excluded, keys, found_keys, additional_keys)
701
648
  end
649
+ found ||= entry_found
650
+ nonexistent ||= entry_nonexistent
651
+ result.concat(entry_names)
702
652
  end
703
- first_entry = found_keys.keys.sort.first
653
+
654
+ first_entry = found_keys.keys.min
704
655
  found_keys = found_keys[first_entry]
705
656
  if found_keys
706
657
  if found_keys[0] > 0
@@ -717,13 +668,91 @@ def partition_osdep_entry(osdep_name, dep_def, handler_names, excluded, *keys)
717
668
  else false
718
669
  end
719
670
 
720
- return found, result
671
+ [found, result]
672
+ end
673
+
674
+ def partition_osdep_raw_array_entry(names, osdep_name, handler_names,
675
+ excluded, keys, additional_keys)
676
+ have_handler_names = true if handler_names
677
+
678
+ # Raw array of packages. Possible only if we are not at toplevel
679
+ # (i.e. if we already have a handler)
680
+ if names == 'ignore'
681
+ [!have_handler_names, false, []]
682
+ elsif names == 'nonexistent'
683
+ [false, !have_handler_names, []]
684
+ elsif !handler_names && names.kind_of?(Array)
685
+ [true, false, names]
686
+ elsif names.respond_to?(:to_str)
687
+ if excluded.include?(names)
688
+ [false, false, []]
689
+ elsif handler_names&.include?(names)
690
+ [true, false, [osdep_name]]
691
+ elsif !handler_names
692
+ [true, false, [names]]
693
+ else
694
+ [false, false, []]
695
+ end
696
+ elsif names.respond_to?(:to_hash)
697
+ rec_found, rec_result = partition_osdep_entry(osdep_name,
698
+ names, handler_names, excluded, keys, *additional_keys)
699
+ if rec_found == FOUND_NONEXISTENT
700
+ [false, true, rec_result]
701
+ elsif rec_found == FOUND_PACKAGES
702
+ [true, false, rec_result]
703
+ else
704
+ [false, false, []]
705
+ end
706
+ else
707
+ [false, false, []]
708
+ end
709
+ end
710
+
711
+ def partition_osdep_map_entry(names, values, osdep_name, handler_names,
712
+ excluded, keys, found_keys, additional_keys)
713
+ # names could be an array already
714
+ names = names.split(',') if names.respond_to?(:to_str)
715
+ result = [false, false, []]
716
+
717
+ if handler_names
718
+ matching_handler = handler_names.
719
+ find { |k| names.any? { |name_tag| k == name_tag.downcase } }
720
+ if matching_handler
721
+ rec_found, rec_result = partition_osdep_entry(
722
+ osdep_name, values, nil, excluded, keys, *additional_keys)
723
+ if rec_found == FOUND_NONEXISTENT
724
+ result = [false, true, rec_result]
725
+ elsif rec_found == FOUND_PACKAGES
726
+ result = [true, false, rec_result]
727
+ end
728
+ end
729
+ end
730
+
731
+ matching_name = keys.
732
+ find { |k| names.any? { |name_tag| k == name_tag.downcase } }
733
+ return result unless matching_name
734
+
735
+ rec_found, rec_result = partition_osdep_entry(
736
+ osdep_name, values, handler_names, excluded, *additional_keys)
737
+ # We only consider the first highest-priority entry,
738
+ # regardless of whether it has some packages for us or
739
+ # not
740
+ idx = keys.index(matching_name)
741
+ if !rec_found
742
+ found_keys[idx] = nil unless found_keys.key?(idx)
743
+ else
744
+ found_keys[idx] ||= [0, []]
745
+ found_keys[idx][0] += rec_found
746
+ found_keys[idx][1].concat(rec_result)
747
+ end
748
+ result
721
749
  end
722
750
 
723
751
  # Resolves the given OS dependencies into the actual packages that need
724
752
  # to be installed on this particular OS.
725
753
  #
726
- # @param [Array<String>] dependencies the list of osdep names that should be resolved
754
+ # @param [Array<String>] dependencies the list of osdep names that
755
+ # should be resolved
727
756
  # @return [Array<#install,Array<String>>] the set of packages, grouped
728
757
  # by the package handlers that should be used to install them
729
758
  #
@@ -733,25 +762,33 @@ def resolve_os_packages(dependencies)
733
762
  all_packages = []
734
763
  dependencies.each do |name|
735
764
  result = resolve_package(name)
736
- if !result
765
+ unless result
737
766
  path = resolve_name(name)
738
- raise MissingOSDep.new, "there is no osdeps definition for #{path.last} (search tree: #{path.join("->")})"
767
+ raise MissingOSDep.new, "there is no osdeps definition "\
768
+ "for #{path.last} (search tree: #{path.join('->')})"
739
769
  end
740
770
 
741
771
  if result.empty?
742
772
  os_names, os_versions = operating_system
743
773
  if os_names.empty?
744
- raise MissingOSDep.new, "there is an osdeps definition for #{name}, but autoproj cannot detect the local operation system"
774
+ raise MissingOSDep.new, "there is an osdeps "\
775
+ "definition for #{name}, but autoproj cannot "\
776
+ "detect the local operation system"
745
777
  else
746
- raise MissingOSDep.new, "there is an osdeps definition for #{name}, but not for this operating system and version (resp. #{os_names.join(", ")} and #{os_versions.join(", ")})"
778
+ raise MissingOSDep.new, "there is an osdeps "\
779
+ "definition for #{name}, but not for this "\
780
+ "operating system and version resp. "\
781
+ "#{os_names.join(', ')} and #{os_versions.join(', ')})"
747
782
  end
748
783
  end
749
784
 
750
785
  result.each do |handler, status, packages|
751
786
  if status == FOUND_NONEXISTENT
752
- raise MissingOSDep.new, "there is an osdep definition for #{name}, and it explicitely states that this package does not exist on your OS"
787
+ raise MissingOSDep.new, "there is an osdep "\
788
+ "definition for #{name}, and it explicitely "\
789
+ "states that this package does not exist on your OS"
753
790
  end
754
- if entry = all_packages.find { |h, _| h == handler }
791
+ if (entry = all_packages.find { |h, _| h == handler })
755
792
  entry[1].concat(packages)
756
793
  else
757
794
  all_packages << [handler, packages.dup]
@@ -759,22 +796,22 @@ def resolve_os_packages(dependencies)
759
796
  end
760
797
  end
761
798
 
762
- all_packages.delete_if do |handler, pkg|
799
+ all_packages.delete_if do |_handler, pkg|
763
800
  pkg.empty?
764
801
  end
765
- return all_packages
802
+ all_packages
766
803
  end
767
804
 
768
805
  # Returns true if the given name has an entry in the osdeps
769
806
  def include?(name)
770
- definitions.has_key?(name)
807
+ definitions.key?(name)
771
808
  end
772
809
 
773
810
  # Returns true if +name+ is an acceptable OS package for this OS and
774
811
  # version
775
812
  def has?(name)
776
813
  status = availability_of(name)
777
- status == AVAILABLE || status == IGNORE
814
+ [AVAILABLE, IGNORE].include?(status)
778
815
  end
779
816
 
780
817
  # Value returned by #availability_of if the required package has no
@@ -809,9 +846,7 @@ def has?(name)
809
846
  # be installed for it
810
847
  def availability_of(name)
811
848
  resolved = resolve_package(name)
812
- if !resolved
813
- return NO_PACKAGE
814
- end
849
+ return NO_PACKAGE unless resolved
815
850
 
816
851
  if resolved.empty?
817
852
  if known_operating_system?
@@ -821,7 +856,9 @@ def availability_of(name)
821
856
  end
822
857
  end
823
858
 
824
- resolved = resolved.find_all { |_, status, list| status != FOUND_PACKAGES || !list.empty? }
859
+ resolved = resolved.find_all do |_, status, list|
860
+ status != FOUND_PACKAGES || !list.empty?
861
+ end
825
862
  failed = resolved.find_all do |_, status, _|
826
863
  status == FOUND_NONEXISTENT
827
864
  end
@@ -837,4 +874,3 @@ def availability_of(name)
837
874
  end
838
875
  end
839
876
  end
840
-