autoproj 2.0.0.rc37 → 2.0.0.rc38

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