autoproj 2.0.0.rc37 → 2.0.0.rc38

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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -2
  3. data/Rakefile +1 -1
  4. data/bin/autoproj_bootstrap +34 -2
  5. data/bin/autoproj_bootstrap.in +4 -2
  6. data/bin/autoproj_install +34 -2
  7. data/bin/autoproj_install.in +4 -2
  8. data/lib/autoproj.rb +9 -2
  9. data/lib/autoproj/autobuild.rb +13 -742
  10. data/lib/autoproj/autobuild_extensions/archive_importer.rb +44 -0
  11. data/lib/autoproj/autobuild_extensions/dsl.rb +439 -0
  12. data/lib/autoproj/autobuild_extensions/git.rb +116 -0
  13. data/lib/autoproj/autobuild_extensions/package.rb +159 -0
  14. data/lib/autoproj/autobuild_extensions/svn.rb +11 -0
  15. data/lib/autoproj/cli/base.rb +17 -18
  16. data/lib/autoproj/cli/clean.rb +1 -2
  17. data/lib/autoproj/cli/envsh.rb +1 -2
  18. data/lib/autoproj/cli/inspection_tool.rb +12 -21
  19. data/lib/autoproj/cli/locate.rb +130 -73
  20. data/lib/autoproj/cli/main.rb +31 -5
  21. data/lib/autoproj/cli/main_plugin.rb +79 -0
  22. data/lib/autoproj/cli/main_test.rb +19 -5
  23. data/lib/autoproj/cli/osdeps.rb +1 -2
  24. data/lib/autoproj/cli/patcher.rb +21 -0
  25. data/lib/autoproj/cli/query.rb +34 -41
  26. data/lib/autoproj/cli/show.rb +121 -52
  27. data/lib/autoproj/cli/status.rb +4 -5
  28. data/lib/autoproj/cli/tag.rb +1 -1
  29. data/lib/autoproj/cli/test.rb +7 -6
  30. data/lib/autoproj/cli/update.rb +8 -22
  31. data/lib/autoproj/cli/versions.rb +1 -2
  32. data/lib/autoproj/configuration.rb +1 -1
  33. data/lib/autoproj/environment.rb +2 -7
  34. data/lib/autoproj/exceptions.rb +10 -8
  35. data/lib/autoproj/find_workspace.rb +46 -12
  36. data/lib/autoproj/installation_manifest.rb +34 -25
  37. data/lib/autoproj/local_package_set.rb +86 -0
  38. data/lib/autoproj/manifest.rb +448 -503
  39. data/lib/autoproj/metapackage.rb +31 -5
  40. data/lib/autoproj/ops/configuration.rb +46 -45
  41. data/lib/autoproj/ops/import.rb +150 -60
  42. data/lib/autoproj/ops/install.rb +25 -1
  43. data/lib/autoproj/ops/loader.rb +4 -1
  44. data/lib/autoproj/ops/main_config_switcher.rb +4 -4
  45. data/lib/autoproj/ops/snapshot.rb +4 -3
  46. data/lib/autoproj/os_package_installer.rb +105 -46
  47. data/lib/autoproj/os_package_resolver.rb +63 -36
  48. data/lib/autoproj/package_definition.rb +1 -0
  49. data/lib/autoproj/package_managers/apt_dpkg_manager.rb +30 -27
  50. data/lib/autoproj/package_managers/bundler_manager.rb +64 -18
  51. data/lib/autoproj/package_managers/gem_manager.rb +4 -2
  52. data/lib/autoproj/package_managers/manager.rb +26 -7
  53. data/lib/autoproj/package_managers/shell_script_manager.rb +4 -4
  54. data/lib/autoproj/package_managers/zypper_manager.rb +1 -1
  55. data/lib/autoproj/package_manifest.rb +154 -137
  56. data/lib/autoproj/package_selection.rb +16 -2
  57. data/lib/autoproj/package_set.rb +352 -309
  58. data/lib/autoproj/query.rb +13 -1
  59. data/lib/autoproj/system.rb +2 -2
  60. data/lib/autoproj/test.rb +164 -11
  61. data/lib/autoproj/variable_expansion.rb +15 -42
  62. data/lib/autoproj/vcs_definition.rb +93 -76
  63. data/lib/autoproj/version.rb +1 -1
  64. data/lib/autoproj/workspace.rb +116 -80
  65. metadata +10 -2
@@ -33,6 +33,7 @@ def initialize(root_dir)
33
33
  @root_dir = root_dir
34
34
  @gem_source = "https://rubygems.org"
35
35
  @gemfile = nil
36
+ @skip_stage2 = false
36
37
 
37
38
  @autoproj_options = Array.new
38
39
 
@@ -103,6 +104,11 @@ def autoproj_gemfile_path; File.join(dot_autoproj, 'Gemfile') end
103
104
  # @return [String]
104
105
  def autoproj_config_path; File.join(dot_autoproj, 'config.yml') end
105
106
 
107
+ # Whether the stage2 install should be called or not
108
+ def skip_stage2?; !!@skip_stage2 end
109
+ # (see #skip_stage2?)
110
+ def skip_stage2=(flag); @skip_stage2 = flag end
111
+
106
112
  # Whether we can access the network while installing
107
113
  def local?; !!@local end
108
114
  # (see #local?)
@@ -186,6 +192,9 @@ def parse_options(args = ARGV)
186
192
  opt.on '--local', 'do not access the network (may fail)' do
187
193
  @local = true
188
194
  end
195
+ opt.on '--skip-stage2', 'do not run the stage2 install' do
196
+ @skip_stage2 = true
197
+ end
189
198
  opt.on '--gem-source=URL', String, "use this source for RubyGems instead of rubygems.org" do |url|
190
199
  @gem_source = url
191
200
  end
@@ -337,6 +346,7 @@ def self.shim_bundler(ruby_executable, autoproj_gemfile_path, gems_gem_home)
337
346
  end
338
347
  end
339
348
 
349
+ ENV['BUNDLE_GEMFILE'] ||= '#{autoproj_gemfile_path}'
340
350
  ENV['GEM_HOME'] = '#{gems_gem_home}'
341
351
  ENV.delete('GEM_PATH')
342
352
  Gem.paths = Hash['GEM_HOME' => '#{gems_gem_home}', 'GEM_PATH' => '']
@@ -349,8 +359,10 @@ def self.shim_script(ruby_executable, autoproj_gemfile_path, gems_gem_home, load
349
359
 
350
360
  if defined?(Bundler)
351
361
  Bundler.with_clean_env do
352
- exec($0, *ARGV)
362
+ exec(Hash['RUBYLIB' => nil], $0, *ARGV)
353
363
  end
364
+ elsif ENV['RUBYLIB']
365
+ exec(Hash['RUBYLIB' => nil], $0, *ARGV)
354
366
  end
355
367
 
356
368
  ENV['BUNDLE_GEMFILE'] = '#{autoproj_gemfile_path}'
@@ -397,6 +409,18 @@ def save_gemfile
397
409
  default_gemfile_contents
398
410
  end
399
411
 
412
+ gemfile += [
413
+ "",
414
+ "config_path = File.join(__dir__, 'config.yml')",
415
+ "if File.file?(config_path)",
416
+ " require 'yaml'",
417
+ " config = YAML.load(File.read(config_path))",
418
+ " (config['plugins'] || Hash.new).each do |plugin_name, (version, options)|",
419
+ " gem plugin_name, version, **options",
420
+ " end",
421
+ "end"
422
+ ].join("\n")
423
+
400
424
  FileUtils.mkdir_p File.dirname(autoproj_gemfile_path)
401
425
  File.open(autoproj_gemfile_path, 'w') do |io|
402
426
  io.write gemfile
@@ -15,7 +15,10 @@ def initialize(root_dir)
15
15
  end
16
16
 
17
17
  def in_package_set(pkg_set, path)
18
- @file_stack.push([pkg_set, File.expand_path(path).gsub(/^#{Regexp.quote(root_dir)}\//, '')])
18
+ if path
19
+ path = File.expand_path(path, root_dir)
20
+ end
21
+ @file_stack.push([pkg_set, path])
19
22
  yield
20
23
  ensure
21
24
  @file_stack.pop
@@ -107,7 +107,7 @@ def bootstrap(buildconf_info, options = Hash.new)
107
107
 
108
108
  elsif buildconf_info.size >= 2 # is a VCS definition for the manifest itself ...
109
109
  type, url, *options = *buildconf_info
110
- url = VCSDefinition.to_absolute_url(url, Dir.pwd)
110
+ url = VCSDefinition.to_absolute_url(url, ws.root_dir)
111
111
  do_switch_config(false, type, url, *options)
112
112
  end
113
113
  ws.env.export_env_sh(nil, shell_helpers: ws.config.shell_helpers?)
@@ -125,7 +125,7 @@ def switch_config(*args)
125
125
  end
126
126
  options = args
127
127
 
128
- url = VCSDefinition.to_absolute_url(url)
128
+ url = VCSDefinition.to_absolute_url(url, ws.root_dir)
129
129
 
130
130
  if vcs && (vcs.type == type && vcs.url == url)
131
131
  vcs = vcs.to_hash
@@ -157,7 +157,7 @@ def switch_config(*args)
157
157
  def do_switch_config(delete_current, type, url, *options)
158
158
  vcs_def = Hash.new
159
159
  vcs_def[:type] = type
160
- vcs_def[:url] = VCSDefinition.to_absolute_url(url)
160
+ vcs_def[:url] = VCSDefinition.to_absolute_url(url, ws.root_dir)
161
161
  options.each do |opt|
162
162
  name, value = opt.split("=")
163
163
  if value =~ /^\d+$/
@@ -170,7 +170,7 @@ def do_switch_config(delete_current, type, url, *options)
170
170
  vcs = VCSDefinition.from_raw(vcs_def)
171
171
 
172
172
  # Install the OS dependencies required for this VCS
173
- ws.install_os_packages([vcs.type])
173
+ ws.install_os_packages([vcs.type], all: nil)
174
174
 
175
175
  # Now check out the actual configuration
176
176
  config_dir = File.join(ws.root_dir, "autoproj")
@@ -134,7 +134,7 @@ def snapshot_packages(packages, target_dir = nil, options = Hash.new)
134
134
 
135
135
  result = Array.new
136
136
  packages.each do |package_name|
137
- package = manifest.packages[package_name]
137
+ package = manifest.find_package_definition(package_name)
138
138
  if !package
139
139
  raise ArgumentError, "#{package_name} is not a known package"
140
140
  end
@@ -217,8 +217,9 @@ def update_package_import_state(name, packages)
217
217
  if current_versions.empty?
218
218
  # Do a full snapshot this time only
219
219
  Autoproj.message " building initial autoproj import log, this may take a while"
220
- packages = manifest.all_selected_packages.
221
- find_all { |pkg| File.directory?(manifest.find_package(pkg).autobuild.srcdir) }
220
+ packages = manifest.all_selected_source_packages.
221
+ find_all { |pkg| File.directory?(pkg.autobuild.srcdir) }.
222
+ map(&:name)
222
223
  end
223
224
  versions = snapshot_package_sets
224
225
  versions += snapshot_packages(packages)
@@ -33,9 +33,6 @@ class OSPackageInstaller
33
33
 
34
34
  attr_reader :os_package_resolver
35
35
 
36
- # The set of packages that have already been installed
37
- attr_reader :installed_packages
38
-
39
36
  # The set of resolved packages that have already been installed
40
37
  attr_reader :installed_resolved_packages
41
38
 
@@ -46,13 +43,18 @@ class << self
46
43
  attr_accessor :force_osdeps
47
44
  end
48
45
 
49
- def initialize(ws, os_package_resolver)
46
+ def initialize(ws, os_package_resolver, package_managers: PACKAGE_MANAGERS)
50
47
  @ws = ws
51
48
  @os_package_resolver = os_package_resolver
52
- @installed_packages = Set.new
49
+ @os_package_manager = nil
53
50
  @installed_resolved_packages = Hash.new { |h, k| h[k] = Set.new }
54
51
  @silent = true
55
52
  @filter_uptodate_packages = true
53
+
54
+ @package_managers = Hash.new
55
+ package_managers.each do |name, klass|
56
+ @package_managers[name] = klass.new(ws)
57
+ end
56
58
  end
57
59
 
58
60
  # Returns the package manager object for the current OS
@@ -66,15 +68,7 @@ def os_package_manager
66
68
  end
67
69
 
68
70
  # Returns the set of package managers
69
- def package_managers
70
- if !@package_managers
71
- @package_managers = Hash.new
72
- PACKAGE_MANAGERS.each do |name, klass|
73
- @package_managers[name] = klass.new(ws)
74
- end
75
- end
76
- @package_managers
77
- end
71
+ attr_reader :package_managers
78
72
 
79
73
  def each_manager(&block)
80
74
  package_managers.each_value(&block)
@@ -172,9 +166,9 @@ def define_osdeps_mode_option
172
166
  end
173
167
 
174
168
  def osdeps_mode_string_to_value(string)
175
- string = string.to_s.downcase.split(',')
169
+ user_modes = string.to_s.downcase.split(',')
176
170
  modes = []
177
- string.map do |str|
171
+ user_modes.each do |str|
178
172
  case str
179
173
  when 'all' then modes.concat(['os', 'gem', 'pip'])
180
174
  when 'ruby' then modes << 'gem'
@@ -182,7 +176,12 @@ def osdeps_mode_string_to_value(string)
182
176
  when 'pip' then modes << 'pip'
183
177
  when 'os' then modes << 'os'
184
178
  when 'none' then
185
- else raise ArgumentError, "#{str} is not a known package handler"
179
+ else
180
+ if package_managers.has_key?(str)
181
+ modes << str
182
+ else
183
+ raise ArgumentError, "#{str} is not a known package handler, known handlers are #{package_managers.keys.sort.join(", ")}"
184
+ end
186
185
  end
187
186
  end
188
187
  modes
@@ -268,7 +267,7 @@ def setup_package_managers(osdeps_mode: self.osdeps_mode)
268
267
  elsif pkg = package_managers[m]
269
268
  pkg.enabled = true
270
269
  else
271
- Autoproj.warn "osdep handler #{m.inspect} has no handler, available handlers are #{package_managers.keys.map(&:inspect).sort.join(", ")}"
270
+ Autoproj.warn "osdep handler #{m.inspect} found in osdep_mode has no handler, available handlers are #{package_managers.keys.map(&:inspect).sort.join(", ")}"
272
271
  end
273
272
  end
274
273
  os_package_manager.silent = self.silent?
@@ -314,45 +313,105 @@ def pristine(packages, options = Hash.new)
314
313
  end
315
314
  end
316
315
 
317
- # Requests the installation of the given set of packages
318
- def install(osdep_packages, install_only: false, run_package_managers_without_packages: false, **options)
319
- osdep_packages = osdep_packages.to_set - installed_packages
320
-
321
- setup_package_managers(**options)
322
-
323
- managers = package_managers.dup
324
- packages = os_package_resolver.resolve_os_packages(osdep_packages)
325
- packages = packages.map do |handler_name, list|
326
- if manager = managers.delete(handler_name)
327
- [manager, list]
316
+ # @api private
317
+ #
318
+ # Resolves the package managers from their name in a manager-to-package
319
+ # list mapping.
320
+ #
321
+ # This is a helper method to resolve the value returned by
322
+ # {OSPackageResolver#resolve_os_packages}
323
+ #
324
+ # @raise [ArgumentError] if a manager name cannot be resolved
325
+ def resolve_package_managers_in_mapping(mapping)
326
+ resolved = Hash.new
327
+ mapping.each do |manager_name, package_list|
328
+ if manager = package_managers[manager_name]
329
+ resolved[manager] = package_list
328
330
  else
329
331
  raise ArgumentError, "no package manager called #{handler_name} found"
330
332
  end
331
333
  end
334
+ resolved
335
+ end
332
336
 
333
- managers.each_value do |pkg_manager|
334
- packages << [pkg_manager, []]
337
+ # @api private
338
+ #
339
+ # Resolves and partitions osdep packages into the various package
340
+ # managers. The returned hash will have one entry per package manager
341
+ # that has a package, with additional entries for package managers that
342
+ # have an empty list but for which
343
+ # {PackageManagers::Manager#call_while_empty?} returns true
344
+ #
345
+ # @param [Array<String>] osdep_packages the list of osdeps to install
346
+ # @return [Hash<PackageManagers::Manager,Array<(String, String)>] the
347
+ # resolved and partitioned osdeps
348
+ # @raise (see #resolve_package_managers_in_mapping)
349
+ # @raise [InternalError] if all_osdep_packages is not provided (is nil)
350
+ # and some strict package managers need to be called to handle
351
+ # osdep_packages
352
+ def resolve_and_partition_osdep_packages(osdep_packages, all_osdep_packages = nil)
353
+ packages = os_package_resolver.resolve_os_packages(osdep_packages)
354
+ packages = resolve_package_managers_in_mapping(packages)
355
+ all_packages = os_package_resolver.resolve_os_packages(all_osdep_packages || Array.new)
356
+ all_packages = resolve_package_managers_in_mapping(all_packages)
357
+
358
+ partitioned_packages = Hash.new
359
+ package_managers.each do |manager_name, manager|
360
+ manager_selected = packages.fetch(manager, Set.new).to_set
361
+ manager_all = all_packages.fetch(manager, Set.new).to_set
362
+
363
+ next if manager_selected.empty? && !manager.call_while_empty?
364
+
365
+ # If the manager is strict, we need to bypass it if we did not
366
+ # get the complete list of osdep packages
367
+ if manager.strict? && !all_osdep_packages
368
+ if !manager_selected.empty?
369
+ 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"
370
+ end
371
+ next
372
+ end
373
+
374
+ if manager.strict?
375
+ manager_packages = manager_all | manager_selected
376
+ else
377
+ manager_packages = manager_selected
378
+ end
379
+
380
+ partitioned_packages[manager] = manager_packages
335
381
  end
382
+ partitioned_packages
383
+ end
384
+
385
+ # Requests the installation of the given set of packages
386
+ def install(osdep_packages, all: nil, install_only: false, run_package_managers_without_packages: false, **options)
387
+ setup_package_managers(**options)
388
+ partitioned_packages =
389
+ resolve_and_partition_osdep_packages(osdep_packages, all)
336
390
 
337
391
  # Install OS packages first, as the other package handlers might
338
392
  # depend on OS packages
339
- os_packages, other_packages = packages.partition do |handler, list|
340
- handler == os_package_manager
393
+ if os_packages = partitioned_packages.delete(os_package_manager)
394
+ install_manager_packages(os_package_manager, os_packages,
395
+ install_only: install_only,
396
+ run_package_managers_without_packages: run_package_managers_without_packages)
341
397
  end
342
- [os_packages, other_packages].each do |packages|
343
- packages.each do |handler, list|
344
- list = list.to_set - installed_resolved_packages[handler]
345
-
346
- if !list.empty? || (run_package_managers_without_packages && handler.call_while_empty?)
347
- handler.install(
348
- list.to_a,
349
- filter_uptodate_packages: filter_uptodate_packages?,
350
- install_only: install_only)
351
- installed_resolved_packages[handler].merge(list)
352
- end
353
- end
398
+ partitioned_packages.each do |manager, package_list|
399
+ install_manager_packages(manager, package_list,
400
+ install_only: install_only,
401
+ run_package_managers_without_packages: run_package_managers_without_packages)
402
+ end
403
+ end
404
+
405
+ def install_manager_packages(manager, package_list, install_only: false, run_package_managers_without_packages: false)
406
+ list = package_list.to_set - installed_resolved_packages[manager]
407
+
408
+ if !list.empty? || run_package_managers_without_packages
409
+ manager.install(
410
+ list.to_a,
411
+ filter_uptodate_packages: filter_uptodate_packages?,
412
+ install_only: install_only)
413
+ installed_resolved_packages[manager].merge(list)
354
414
  end
355
- installed_packages.merge(packages)
356
415
  end
357
416
  end
358
417
  end
@@ -17,7 +17,7 @@ class << self
17
17
  end
18
18
  @suffixes = []
19
19
 
20
- def self.load(file)
20
+ def self.load(file, **options)
21
21
  if !File.file?(file)
22
22
  raise ArgumentError, "no such file or directory #{file}"
23
23
  end
@@ -29,18 +29,18 @@ def self.load(file)
29
29
  else ArgumentError
30
30
  end
31
31
 
32
- result = new
33
- candidates.each do |file|
34
- next if !File.file?(file)
35
- file = File.expand_path(file)
32
+ result = new(**options)
33
+ candidates.each do |file_candidate|
34
+ next if !File.file?(file_candidate)
35
+ file_candidate = File.expand_path(file_candidate)
36
36
  begin
37
- data = YAML.load(File.read(file)) || Hash.new
37
+ data = YAML.load(File.read(file_candidate)) || Hash.new
38
38
  verify_definitions(data)
39
39
  rescue *error_t => e
40
- raise ConfigError.new, "error in #{file}: #{e.message}", e.backtrace
40
+ raise ConfigError.new, "error in #{file_candidate}: #{e.message}", e.backtrace
41
41
  end
42
42
 
43
- result.merge(new(data, file))
43
+ result.merge(new(data, file_candidate, **options))
44
44
  end
45
45
  result
46
46
  end
@@ -128,15 +128,22 @@ def load_default
128
128
  def prefer_indep_over_os_packages?; !!@prefer_indep_over_os_packages end
129
129
  # (see prefer_indep_over_os_packages?)
130
130
  def prefer_indep_over_os_packages=(flag); @prefer_indep_over_os_packages = flag end
131
+ # Cached results of {#resolve_package}
132
+ attr_reader :resolve_package_cache
131
133
 
132
134
  # Use to override the autodetected OS-specific package handler
133
- attr_writer :os_package_manager
135
+ def os_package_manager=(manager_name)
136
+ if manager_name && !package_managers.include?(manager_name)
137
+ raise ArgumentError, "#{manager_name} is not a known package manager"
138
+ end
139
+ @os_package_manager = manager_name
140
+ end
134
141
 
135
142
  # Returns the name of the package manager object for the current OS
136
143
  #
137
144
  # @return [String]
138
145
  def os_package_manager
139
- if !instance_variable_defined?(:@os_package_manager)
146
+ if !@os_package_manager
140
147
  os_names, _ = operating_system
141
148
  os_name = os_names.find { |name| OS_PACKAGE_MANAGERS[name] }
142
149
  @os_package_manager = OS_PACKAGE_MANAGERS[os_name] ||
@@ -152,20 +159,32 @@ def os_package_manager
152
159
 
153
160
  # The Gem::SpecFetcher object that should be used to query RubyGems, and
154
161
  # install RubyGems packages
155
- def initialize(defs = Hash.new, file = nil)
162
+ def initialize(defs = Hash.new, file = nil,
163
+ operating_system: nil,
164
+ package_managers: PACKAGE_MANAGERS.dup,
165
+ os_package_manager: nil)
156
166
  @definitions = defs.to_hash
167
+ @resolve_package_cache = Hash.new
157
168
  @all_definitions = Hash.new { |h, k| h[k] = Array.new }
158
- @package_managers = PACKAGE_MANAGERS.dup
169
+ @package_managers = package_managers
170
+ self.os_package_manager = os_package_manager
171
+
159
172
  @prefer_indep_over_os_packages = false
160
173
 
161
174
  @sources = Hash.new
162
175
  @installed_packages = Set.new
163
- @operating_system = self.class.operating_system
176
+ @operating_system = operating_system
177
+ @supported_operating_system = nil
178
+ @odeps_mode = nil
164
179
  if file
165
180
  defs.each_key do |package_name|
166
181
  sources[package_name] = file
167
182
  all_definitions[package_name] << [[file], defs[package_name]]
168
183
  end
184
+ else
185
+ defs.each_key do |package_name|
186
+ all_definitions[package_name] << [[], defs[package_name]]
187
+ end
169
188
  end
170
189
  end
171
190
 
@@ -174,7 +193,7 @@ def initialize(defs = Hash.new, file = nil)
174
193
  # It includes even the packages for which there are no definitions on
175
194
  # this OS
176
195
  def all_package_names
177
- all_definitions.keys
196
+ definitions.keys
178
197
  end
179
198
 
180
199
  # Returns the full path to the osdeps file from which the package
@@ -183,16 +202,24 @@ def source_of(package_name)
183
202
  sources[package_name]
184
203
  end
185
204
 
205
+ def add_entries(entries, file: nil)
206
+ merge(self.class.new(entries, file))
207
+ end
208
+
209
+ def invalidate_resolve_package_cache
210
+ @resolve_package_cache.clear
211
+ end
212
+
186
213
  # Merges the osdeps information of +info+ into +self+. If packages are
187
214
  # defined in both OSPackageResolver objects, the information in +info+
188
215
  # takes precedence
189
216
  def merge(info)
190
- root_dir = nil
217
+ invalidate_resolve_package_cache
218
+
191
219
  @definitions = definitions.merge(info.definitions) do |h, v1, v2|
192
220
  if v1 != v2
193
- root_dir ||= "#{Autoproj.root_dir}/"
194
- old = source_of(h).gsub(root_dir, '')
195
- new = info.source_of(h).gsub(root_dir, '')
221
+ old = source_of(h)
222
+ new = info.source_of(h)
196
223
 
197
224
  # Warn if the new osdep definition resolves to a different
198
225
  # set of packages than the old one
@@ -247,12 +274,7 @@ def self.verify_definitions(hash, path = [])
247
274
  # system on which we are installed
248
275
  def supported_operating_system?
249
276
  if @supported_operating_system.nil?
250
- os_names, _ = operating_system
251
- @supported_operating_system =
252
- if !os_names then false
253
- else
254
- os_names.any? { |os_name| OS_PACKAGE_MANAGERS.has_key?(os_name) }
255
- end
277
+ @supported_operating_system = (os_package_manager != 'unknown')
256
278
  end
257
279
  return @supported_operating_system
258
280
  end
@@ -337,21 +359,18 @@ def self.normalize_os_representation(names, versions)
337
359
  return names, versions
338
360
  end
339
361
 
362
+ # The operating system self is targetting
363
+ #
364
+ # If unset in {#initialize} or by calling {#operating_system=}, it will
365
+ # attempt to autodetect it on the first call
340
366
  def operating_system
341
- @operating_system || self.class.operating_system
367
+ @operating_system ||= self.class.autodetect_operating_system
342
368
  end
343
369
 
370
+ # Change the operating system this resolver is targetting
344
371
  def operating_system=(values)
345
372
  @supported_operating_system = nil
346
- @operating_system = values
347
- end
348
-
349
- def self.operating_system
350
- @operating_system
351
- end
352
- @operating_system = nil
353
-
354
- def self.operating_system=(values)
373
+ @os_package_manager = nil
355
374
  @operating_system = values
356
375
  end
357
376
 
@@ -471,6 +490,10 @@ def self.resolve_name(name)
471
490
  # name and version. The package list might be empty even if status ==
472
491
  # FOUND_PACKAGES, for instance if the ignore keyword is used.
473
492
  def resolve_package(name)
493
+ if resolve_package_cache.has_key?(name)
494
+ return resolve_package_cache[name]
495
+ end
496
+
474
497
  path = self.class.resolve_name(name)
475
498
  name = path.last
476
499
 
@@ -484,7 +507,7 @@ def resolve_package(name)
484
507
 
485
508
  dep_def = definitions[name]
486
509
  if !dep_def
487
- return nil
510
+ return (resolve_package_cache[name] = nil)
488
511
  end
489
512
 
490
513
  # Partition the found definition in all entries that are interesting
@@ -522,7 +545,7 @@ def resolve_package(name)
522
545
  end
523
546
  end
524
547
 
525
- result
548
+ resolve_package_cache[name] = result
526
549
  end
527
550
 
528
551
  # Value returned by #resolve_package and #partition_osdep_entry in
@@ -712,6 +735,10 @@ def resolve_os_packages(dependencies)
712
735
  return all_packages
713
736
  end
714
737
 
738
+ # Returns true if the given name has an entry in the osdeps
739
+ def include?(name)
740
+ definitions.has_key?(name)
741
+ end
715
742
 
716
743
  # Returns true if +name+ is an acceptable OS package for this OS and
717
744
  # version