autoproj 1.13.7 → 2.0.0.b1

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 (89) hide show
  1. checksums.yaml +4 -4
  2. data/.gemtest +0 -0
  3. data/Manifest.txt +27 -21
  4. data/Rakefile +4 -6
  5. data/bin/alocate +5 -1
  6. data/bin/amake +3 -53
  7. data/bin/aup +3 -50
  8. data/bin/autoproj +3 -264
  9. data/bin/autoproj_bootstrap +294 -349
  10. data/bin/autoproj_bootstrap.in +27 -3
  11. data/lib/autoproj.rb +23 -1
  12. data/lib/autoproj/autobuild.rb +51 -89
  13. data/lib/autoproj/base.rb +0 -9
  14. data/lib/autoproj/build_option.rb +1 -3
  15. data/lib/autoproj/cli.rb +1 -0
  16. data/lib/autoproj/cli/base.rb +155 -0
  17. data/lib/autoproj/cli/bootstrap.rb +119 -0
  18. data/lib/autoproj/cli/build.rb +72 -0
  19. data/lib/autoproj/cli/cache.rb +31 -0
  20. data/lib/autoproj/cli/clean.rb +37 -0
  21. data/lib/autoproj/cli/commit.rb +41 -0
  22. data/lib/autoproj/cli/doc.rb +22 -0
  23. data/lib/autoproj/cli/envsh.rb +22 -0
  24. data/lib/autoproj/cli/inspection_tool.rb +73 -0
  25. data/lib/autoproj/cli/locate.rb +96 -0
  26. data/lib/autoproj/cli/log.rb +26 -0
  27. data/lib/autoproj/cli/main.rb +249 -0
  28. data/lib/autoproj/cli/main_test.rb +57 -0
  29. data/lib/autoproj/cli/osdeps.rb +30 -0
  30. data/lib/autoproj/cli/query.rb +43 -0
  31. data/lib/autoproj/cli/reconfigure.rb +19 -0
  32. data/lib/autoproj/cli/reset.rb +7 -32
  33. data/lib/autoproj/cli/show.rb +219 -0
  34. data/lib/autoproj/cli/snapshot.rb +1 -1
  35. data/lib/autoproj/cli/status.rb +149 -0
  36. data/lib/autoproj/cli/switch_config.rb +28 -0
  37. data/lib/autoproj/cli/tag.rb +9 -35
  38. data/lib/autoproj/cli/test.rb +34 -55
  39. data/lib/autoproj/cli/update.rb +158 -0
  40. data/lib/autoproj/cli/versions.rb +32 -69
  41. data/lib/autoproj/configuration.rb +95 -34
  42. data/lib/autoproj/default.osdeps +25 -35
  43. data/lib/autoproj/environment.rb +85 -63
  44. data/lib/autoproj/exceptions.rb +50 -0
  45. data/lib/autoproj/gitorious.rb +11 -9
  46. data/lib/autoproj/manifest.rb +199 -231
  47. data/lib/autoproj/metapackage.rb +0 -8
  48. data/lib/autoproj/ops/build.rb +1 -17
  49. data/lib/autoproj/ops/configuration.rb +92 -90
  50. data/lib/autoproj/ops/import.rb +222 -0
  51. data/lib/autoproj/ops/loader.rb +18 -8
  52. data/lib/autoproj/ops/main_config_switcher.rb +45 -73
  53. data/lib/autoproj/ops/snapshot.rb +5 -10
  54. data/lib/autoproj/ops/tools.rb +10 -44
  55. data/lib/autoproj/options.rb +35 -6
  56. data/lib/autoproj/osdeps.rb +97 -68
  57. data/lib/autoproj/package_selection.rb +39 -20
  58. data/lib/autoproj/package_set.rb +26 -24
  59. data/lib/autoproj/reporter.rb +91 -0
  60. data/lib/autoproj/system.rb +50 -149
  61. data/lib/autoproj/variable_expansion.rb +32 -6
  62. data/lib/autoproj/vcs_definition.rb +57 -17
  63. data/lib/autoproj/version.rb +1 -1
  64. data/lib/autoproj/workspace.rb +550 -0
  65. data/test/ops/test_snapshot.rb +26 -0
  66. data/test/test_package.rb +30 -0
  67. data/test/test_vcs_definition.rb +46 -0
  68. metadata +55 -50
  69. data/bin/autolocate +0 -3
  70. data/bin/autoproj-bootstrap +0 -68
  71. data/bin/autoproj-cache +0 -18
  72. data/bin/autoproj-clean +0 -13
  73. data/bin/autoproj-commit +0 -10
  74. data/bin/autoproj-create-set +0 -118
  75. data/bin/autoproj-doc +0 -28
  76. data/bin/autoproj-envsh +0 -14
  77. data/bin/autoproj-list +0 -69
  78. data/bin/autoproj-locate +0 -85
  79. data/bin/autoproj-log +0 -5
  80. data/bin/autoproj-query +0 -82
  81. data/bin/autoproj-reset +0 -13
  82. data/bin/autoproj-show +0 -192
  83. data/bin/autoproj-snapshot +0 -27
  84. data/bin/autoproj-switch-config +0 -24
  85. data/bin/autoproj-tag +0 -13
  86. data/bin/autoproj-test +0 -31
  87. data/bin/autoproj-versions +0 -20
  88. data/bin/autoproj_stress_test +0 -40
  89. data/lib/autoproj/cmdline.rb +0 -1649
@@ -38,14 +38,6 @@ module Autoproj
38
38
  @packages.each(&block)
39
39
  end
40
40
 
41
- # Filter this metapackage by removing some packages
42
- def remove(pkg)
43
- if !pkg.respond_to?(:to_str)
44
- pkg = pkg.name
45
- end
46
- @packages.delete_if { |p| p.name == pkg }
47
- end
48
-
49
41
  # Tests if the given package is included in this metapackage
50
42
  #
51
43
  # @param [String,#name] pkg the package or package name
@@ -9,14 +9,9 @@ module Autoproj
9
9
  # The manifest on which we operate
10
10
  # @return [Manifest]
11
11
  attr_reader :manifest
12
- # Whether we should update the OS dependencies before building. It
13
- # controls the behaviour of {rebuild_all} as well as
14
- # {build_packages}
15
- attr_predicate :update_os_dependencies?, true
16
12
 
17
- def initialize(manifest, update_os_dependencies = true)
13
+ def initialize(manifest)
18
14
  @manifest = manifest
19
- self.update_os_dependencies = update_os_dependencies
20
15
  end
21
16
 
22
17
  # Triggers a rebuild of all packages
@@ -26,17 +21,6 @@ module Autoproj
26
21
  # non-OS-specific managers that support it (e.g. RubyGems) if
27
22
  # {update_os_dependencies?} is set to true (the default)
28
23
  def rebuild_all
29
- if update_os_dependencies?
30
- # We also reinstall the osdeps that provide the
31
- # functionality
32
- managers = Autoproj.osdeps.setup_package_handlers
33
- managers.each do |mng|
34
- if mng.respond_to?(:reinstall)
35
- mng.reinstall
36
- end
37
- end
38
- end
39
-
40
24
  packages = manifest.all_layout_packages
41
25
  manifest.pristine_os_dependencies(packages)
42
26
  rebuild_packages(packages, packages)
@@ -6,35 +6,19 @@ module Autoproj
6
6
 
7
7
  # Implementation of the operations to manage the configuration
8
8
  class Configuration
9
- # The manifest object that represents the autoproj configuration
10
- #
11
- # @return [Manifest]
12
- attr_reader :manifest
13
-
14
- # The loader object that should be used to load files such as init.rb
15
- attr_reader :loader
16
-
17
- # The main configuration directory
18
- #
19
- # @return [String]
20
- attr_reader :config_dir
9
+ attr_reader :ws
21
10
 
22
11
  # The autoproj install we should update from (if any)
23
12
  #
24
13
  # @return [nil,InstallationManifest]
25
14
  attr_reader :update_from
26
15
 
27
- # The object that allows us to install OS dependencies
28
- def osdeps
29
- Autoproj.osdeps
30
- end
31
-
32
16
  # The path in which remote package sets should be exposed to the
33
17
  # user
34
18
  #
35
19
  # @return [String]
36
20
  def remotes_dir
37
- Autoproj.remotes_dir
21
+ ws.remotes_dir
38
22
  end
39
23
 
40
24
  # The path in which remote package sets should be exposed to the
@@ -42,45 +26,44 @@ module Autoproj
42
26
  #
43
27
  # @return [String]
44
28
  def remotes_user_dir
45
- File.join(config_dir, "remotes")
29
+ File.join(ws.config_dir, "remotes")
46
30
  end
47
31
 
48
32
  # The path to the main manifest file
49
33
  #
50
34
  # @return [String]
51
35
  def manifest_path
52
- File.join(config_dir, 'manifest')
36
+ File.join(ws.config_dir, 'manifest')
53
37
  end
54
38
 
55
-
56
39
  # @param [Manifest] manifest
57
40
  # @param [Loader] loader
58
41
  # @option options [InstallationManifest] :update_from
59
- # (CmdLine.update_from) another autoproj installation from which we
42
+ # another autoproj installation from which we
60
43
  # should update (instead of the normal VCS)
61
- def initialize(manifest, loader, options = Hash.new)
62
- options = Kernel.validate_options options,
63
- :update_from => CmdLine.update_from
64
- @manifest = manifest
65
- @loader = loader
44
+ def initialize(workspace, options = Hash.new)
45
+ options = validate_options options,
46
+ update_from: nil
47
+ @ws = workspace
66
48
  @update_from = options[:update_from]
67
- @config_dir = Autoproj.config_dir
68
49
  @remote_update_message_displayed = false
69
50
  end
70
51
 
71
52
  # Imports or updates a source (remote or otherwise).
72
53
  #
73
54
  # See create_autobuild_package for informations about the arguments.
74
- def self.update_configuration_repository(vcs, name, into, options = Hash.new)
75
- options = Kernel.validate_options options, update_from: nil, only_local: false
76
- update_from, only_local = options.values_at(:update_from, :only_local)
55
+ def update_configuration_repository(vcs, name, into, options = Hash.new)
56
+ options = Kernel.validate_options options,
57
+ only_local: false,
58
+ checkout_only: !Autobuild.do_update,
59
+ ignore_errors: false
77
60
 
78
61
  fake_package = Tools.create_autobuild_package(vcs, name, into)
79
62
  if update_from
80
63
  # Define a package in the installation manifest that points to
81
64
  # the desired folder in other_root
82
65
  relative_path = Pathname.new(into).
83
- relative_path_from(Pathname.new(Autoproj.root_dir)).to_s
66
+ relative_path_from(Pathname.new(root_dir)).to_s
84
67
  other_dir = File.join(update_from.path, relative_path)
85
68
  if File.directory?(other_dir)
86
69
  update_from.packages.unshift(
@@ -96,7 +79,7 @@ module Autoproj
96
79
  fake_package.update = false
97
80
  end
98
81
  end
99
- fake_package.import(only_local: only_local)
82
+ fake_package.import(options)
100
83
 
101
84
  rescue Autobuild::ConfigException => e
102
85
  raise ConfigError.new, "cannot import #{name}: #{e.message}", e.backtrace
@@ -106,13 +89,20 @@ module Autoproj
106
89
  #
107
90
  # @return [Boolean] true if something got updated or checked out,
108
91
  # and false otherwise
109
- def update_main_configuration(only_local = false)
110
- self.class.update_configuration_repository(
111
- manifest.vcs,
92
+ def update_main_configuration(options = Hash.new)
93
+ if !options.kind_of?(Hash)
94
+ options = Hash[only_local: options]
95
+ end
96
+ options = validate_options options,
97
+ only_local: false,
98
+ checkout_only: !Autobuild.do_update,
99
+ ignore_errors: false
100
+
101
+ update_configuration_repository(
102
+ ws.manifest.vcs,
112
103
  "autoproj main configuration",
113
- config_dir,
114
- update_from: update_from,
115
- only_local: only_local)
104
+ ws.config_dir,
105
+ options)
116
106
  end
117
107
 
118
108
  # Update or checkout a remote package set, based on its VCS definition
@@ -120,11 +110,20 @@ module Autoproj
120
110
  # @param [VCSDefinition] vcs the package set VCS
121
111
  # @return [Boolean] true if something got updated or checked out,
122
112
  # and false otherwise
123
- def update_remote_package_set(vcs, only_local = false)
124
- name = PackageSet.name_of(manifest, vcs)
113
+ def update_remote_package_set(vcs, options = Hash.new)
114
+ # BACKWARD
115
+ if !options.kind_of?(Hash)
116
+ options = Hash[only_local: options]
117
+ end
118
+ options = validate_options options,
119
+ only_local: false,
120
+ checkout_only: !Autobuild.do_update,
121
+ ignore_errors: false
122
+
123
+ name = PackageSet.name_of(ws.manifest, vcs)
125
124
  raw_local_dir = PackageSet.raw_local_dir_of(vcs)
126
125
 
127
- return if !Autobuild.do_update && File.exists?(raw_local_dir)
126
+ return if options[:checkout_only] && File.exists?(raw_local_dir)
128
127
 
129
128
  # YUK. I am stopping there in the refactoring
130
129
  # TODO: figure out a better way
@@ -132,11 +131,9 @@ module Autoproj
132
131
  Autoproj.message("autoproj: updating remote definitions of package sets", :bold)
133
132
  @remote_update_message_displayed = true
134
133
  end
135
- osdeps.install([vcs.type])
136
- self.class.update_configuration_repository(
137
- vcs, name, raw_local_dir,
138
- update_from: update_from,
139
- only_local: only_local)
134
+ ws.osdeps.install([vcs.type])
135
+ update_configuration_repository(
136
+ vcs, name, raw_local_dir, options)
140
137
  end
141
138
 
142
139
  # Create the user-visible directory for a remote package set
@@ -144,7 +141,7 @@ module Autoproj
144
141
  # @param [VCSDefinition] vcs the package set VCS
145
142
  # @return [String] the full path to the created user dir
146
143
  def create_remote_set_user_dir(vcs)
147
- name = PackageSet.name_of(manifest, vcs)
144
+ name = PackageSet.name_of(ws.manifest, vcs)
148
145
  raw_local_dir = PackageSet.raw_local_dir_of(vcs)
149
146
  FileUtils.mkdir_p(remotes_user_dir)
150
147
  symlink_dest = File.join(remotes_user_dir, name)
@@ -166,9 +163,9 @@ module Autoproj
166
163
  end
167
164
 
168
165
  def load_package_set(vcs, options, imported_from)
169
- pkg_set = PackageSet.new(manifest, vcs)
166
+ pkg_set = PackageSet.new(ws.manifest, vcs)
170
167
  pkg_set.auto_imports = options[:auto_imports]
171
- loader.load_if_present(pkg_set, pkg_set.local_dir, 'init.rb')
168
+ ws.load_if_present(pkg_set, pkg_set.local_dir, 'init.rb')
172
169
  pkg_set.load_description_file
173
170
  if imported_from
174
171
  pkg_set.imported_from << imported_from
@@ -204,16 +201,22 @@ module Autoproj
204
201
  #
205
202
  # @yieldparam [String] osdep the name of an osdep required to import the
206
203
  # package sets
207
- def load_and_update_package_sets(root_pkg_set, only_local = false)
204
+ def load_and_update_package_sets(root_pkg_set, options = Hash.new)
205
+ if !options.kind_of?(Hash)
206
+ options = Hash[only_local: options]
207
+ end
208
+ options = validate_options options,
209
+ only_local: false,
210
+ checkout_only: !Autobuild.do_update,
211
+ ignore_errors: false
212
+
208
213
  package_sets = [root_pkg_set]
209
214
  by_repository_id = Hash.new
210
215
  by_name = Hash.new
211
216
 
212
- required_remotes_dirs = Array.new
213
-
214
217
  queue = queue_auto_imports_if_needed(Array.new, root_pkg_set, root_pkg_set)
215
218
  while !queue.empty?
216
- vcs, options, imported_from = queue.shift
219
+ vcs, import_options, imported_from = queue.shift
217
220
  repository_id = repository_id_of(vcs)
218
221
  if already_processed = by_repository_id[repository_id]
219
222
  already_processed_vcs, already_processed_from, pkg_set = *already_processed
@@ -229,28 +232,17 @@ module Autoproj
229
232
  end
230
233
  by_repository_id[repository_id] = [vcs, imported_from]
231
234
 
232
- # Make sure the package set has been already checked out to
233
- # retrieve the actual name of the package set
234
235
  if !vcs.local?
235
- update_remote_package_set(vcs, only_local)
236
- raw_local_dir = PackageSet.raw_local_dir_of(vcs)
237
- required_remotes_dirs << raw_local_dir
236
+ update_remote_package_set(vcs, options)
237
+ create_remote_set_user_dir(vcs)
238
238
  end
239
- name = PackageSet.name_of(manifest, vcs)
240
-
241
- required_user_dirs = by_name.collect { |k,v| k }
242
- Autoproj.debug "Trying to load package_set: #{name} from definition #{repository_id}"
243
- Autoproj.debug "Already loaded package_sets are: #{required_user_dirs}"
244
239
 
240
+ name = PackageSet.name_of(ws.manifest, vcs)
245
241
  if already_loaded = by_name[name]
246
242
  already_loaded_pkg_set, already_loaded_vcs = *already_loaded
247
243
  if already_loaded_vcs != vcs
248
244
  if imported_from
249
- Autoproj.warn "redundant auto-import by #{imported_from.name} for package set '#{name}'."
250
- Autoproj.warn " A package set with the same name (#{name}) has already been imported from"
251
- Autoproj.warn " #{already_loaded_vcs}"
252
- Autoproj.warn " Skipping the following one: "
253
- Autoproj.warn " #{vcs}"
245
+ Autoproj.warn "#{imported_from.name} auto-imports a package set from #{vcs}, but a package set with the same name (#{name}) has already been imported from #{already_loaded_vcs}, I am skipping this one"
254
246
  else
255
247
  Autoproj.warn "the manifest refers to a package set from #{vcs}, but a package set with the same name (#{name}) has already been imported from #{already_loaded_vcs}, I am skipping this one"
256
248
  end
@@ -261,11 +253,9 @@ module Autoproj
261
253
  imported_from.imports << already_loaded_pkg_set
262
254
  end
263
255
  next
264
- else
265
- create_remote_set_user_dir(vcs)
266
256
  end
267
257
 
268
- pkg_set = load_package_set(vcs, options, imported_from)
258
+ pkg_set = load_package_set(vcs, import_options, imported_from)
269
259
  by_repository_id[repository_id][2] = pkg_set
270
260
  package_sets << pkg_set
271
261
 
@@ -275,21 +265,18 @@ module Autoproj
275
265
  queue_auto_imports_if_needed(queue, pkg_set, root_pkg_set)
276
266
  end
277
267
 
278
- required_user_dirs = by_name.collect { |k,v| k }
279
- cleanup_remotes_dir(package_sets, required_remotes_dirs)
280
- cleanup_remotes_user_dir(package_sets, required_user_dirs)
268
+ cleanup_remotes_dir(package_sets)
269
+ cleanup_remotes_user_dir(package_sets)
281
270
  package_sets
282
271
  end
283
272
 
284
273
  # Removes from {remotes_dir} the directories that do not match a package
285
274
  # set
286
- def cleanup_remotes_dir(package_sets = manifest.package_sets, required_remotes_dirs = Array.new)
275
+ def cleanup_remotes_dir(package_sets = ws.manifest.package_sets)
287
276
  # Cleanup the .remotes and remotes_symlinks_dir directories
288
277
  Dir.glob(File.join(remotes_dir, '*')).each do |dir|
289
278
  dir = File.expand_path(dir)
290
- # Once a package set has been checked out during the process,
291
- # keep it -- so that it won't be checked out again
292
- if File.directory?(dir) && !required_remotes_dirs.include?(dir)
279
+ if File.directory?(dir) && !package_sets.find { |pkg| pkg.raw_local_dir == dir }
293
280
  FileUtils.rm_rf dir
294
281
  end
295
282
  end
@@ -297,11 +284,10 @@ module Autoproj
297
284
 
298
285
  # Removes from {remotes_user_dir} the directories that do not match a
299
286
  # package set
300
- def cleanup_remotes_user_dir(package_sets = manifest.package_sets, required_user_dirs = Array.new)
287
+ def cleanup_remotes_user_dir(package_sets = ws.manifest.package_sets)
301
288
  Dir.glob(File.join(remotes_user_dir, '*')).each do |file|
302
289
  file = File.expand_path(file)
303
- user_dir = File.basename(file)
304
- if File.symlink?(file) && !required_user_dirs.include?(user_dir)
290
+ if File.symlink?(file) && !package_sets.find { |pkg_set| pkg_set.user_local_dir == file }
305
291
  FileUtils.rm_f file
306
292
  end
307
293
  end
@@ -349,26 +335,42 @@ module Autoproj
349
335
  sorted
350
336
  end
351
337
 
352
- def update_configuration(only_local = false)
338
+ def load_package_sets(options = Hash.new)
339
+ options = validate_options options,
340
+ only_local: false,
341
+ checkout_only: true,
342
+ ignore_errors: false
343
+ update_configuration(options)
344
+ end
345
+
346
+ def update_configuration(options = Hash.new)
347
+ if !options.kind_of?(Hash)
348
+ options = Hash[only_local: options]
349
+ end
350
+ options = validate_options options,
351
+ only_local: false,
352
+ checkout_only: !Autobuild.do_update,
353
+ ignore_errors: false
354
+
353
355
  # Load the installation's manifest a first time, to check if we should
354
356
  # update it ... We assume that the OS dependencies for this VCS is already
355
357
  # installed (i.e. that the user did not remove it)
356
- if manifest.vcs && !manifest.vcs.local?
357
- update_main_configuration(only_local)
358
+ if ws.manifest.vcs && !ws.manifest.vcs.local?
359
+ update_main_configuration(options)
358
360
  end
359
- Tools.load_main_initrb(manifest)
360
- manifest.load(manifest_path)
361
+ ws.load_main_initrb
362
+ ws.manifest.load(manifest_path)
361
363
 
362
- root_pkg_set = manifest.local_package_set
364
+ root_pkg_set = ws.manifest.local_package_set
363
365
  root_pkg_set.load_description_file
364
366
  root_pkg_set.explicit = true
365
- package_sets = load_and_update_package_sets(root_pkg_set, only_local)
367
+ package_sets = load_and_update_package_sets(root_pkg_set, options)
366
368
  root_pkg_set.imports.each do |pkg_set|
367
369
  pkg_set.explicit = true
368
370
  end
369
371
  package_sets = sort_package_sets_by_import_order(package_sets, root_pkg_set)
370
372
  package_sets.each do |pkg_set|
371
- manifest.register_package_set(pkg_set)
373
+ ws.manifest.register_package_set(pkg_set)
372
374
  end
373
375
  # YUK. I am stopping there in the refactoring
374
376
  # TODO: figure out a better way
@@ -0,0 +1,222 @@
1
+ module Autoproj
2
+ module Ops
3
+ class Import
4
+ attr_reader :ws
5
+ def initialize(ws)
6
+ @ws = ws
7
+ end
8
+
9
+ def mark_exclusion_along_revdeps(pkg_name, revdeps, chain = [], reason = nil)
10
+ root = !reason
11
+ chain.unshift pkg_name
12
+ if root
13
+ reason = ws.manifest.exclusion_reason(pkg_name)
14
+ else
15
+ if chain.size == 1
16
+ ws.manifest.add_exclusion(pkg_name, "its dependency #{reason}")
17
+ else
18
+ ws.manifest.add_exclusion(pkg_name, "#{reason} (dependency chain: #{chain.join(">")})")
19
+ end
20
+ end
21
+
22
+ return if !revdeps.has_key?(pkg_name)
23
+ revdeps[pkg_name].each do |dep_name|
24
+ if !ws.manifest.excluded?(dep_name)
25
+ mark_exclusion_along_revdeps(dep_name, revdeps, chain.dup, reason)
26
+ end
27
+ end
28
+ end
29
+
30
+ VALID_OSDEP_AVAILABILITY =
31
+ [OSDependencies::AVAILABLE, OSDependencies::IGNORE]
32
+
33
+ def import_next_step(pkg, reverse_dependencies)
34
+ new_packages = []
35
+ pkg.dependencies.each do |dep_name|
36
+ reverse_dependencies[dep_name] << pkg.name
37
+ new_packages << ws.manifest.find_autobuild_package(dep_name)
38
+ end
39
+ pkg_opt_deps, pkg_opt_os_deps = pkg.partition_optional_dependencies
40
+ pkg_opt_deps.each do |dep_name|
41
+ new_packages << ws.manifest.find_autobuild_package(dep_name)
42
+ end
43
+
44
+ # Handle OS dependencies, excluding the package if some
45
+ # dependencies are not available
46
+ pkg.os_packages.each do |dep_name|
47
+ reverse_dependencies[dep_name] << pkg.name
48
+ end
49
+ (pkg.os_packages | pkg_opt_os_deps).each do |dep_name|
50
+ if ws.manifest.excluded?(dep_name)
51
+ mark_exclusion_along_revdeps(dep_name, reverse_dependencies)
52
+ end
53
+ end
54
+
55
+ new_packages.delete_if do |new_pkg|
56
+ if ws.manifest.excluded?(new_pkg.name)
57
+ mark_exclusion_along_revdeps(new_pkg.name, reverse_dependencies)
58
+ true
59
+ elsif ws.manifest.ignored?(new_pkg.name)
60
+ true
61
+ end
62
+ end
63
+ new_packages
64
+ end
65
+
66
+ def import_packages(selection, options = Hash.new)
67
+ options, import_options = Kernel.filter_options options,
68
+ warn_about_ignored_packages: true,
69
+ warn_about_excluded_packages: true,
70
+ recursive: true
71
+
72
+ manifest = ws.manifest
73
+
74
+ updated_packages = Array.new
75
+ selected_packages = selection.each_source_package_name.map do |pkg_name|
76
+ manifest.find_autobuild_package(pkg_name)
77
+ end.to_set
78
+
79
+ # The set of all packages that are currently selected by +selection+
80
+ all_processed_packages = Set.new
81
+ # The reverse dependencies for the package tree. It is discovered as
82
+ # we go on with the import
83
+ #
84
+ # It only contains strong dependencies. Optional dependencies are
85
+ # not included, as we will use this only to take into account
86
+ # package exclusion (and that does not affect optional dependencies)
87
+ reverse_dependencies = Hash.new { |h, k| h[k] = Set.new }
88
+
89
+ package_queue = selected_packages.to_a.sort_by(&:name)
90
+ while !package_queue.empty?
91
+ pkg = package_queue.shift
92
+ # Remove packages that have already been processed
93
+ next if all_processed_packages.include?(pkg.name)
94
+ all_processed_packages << pkg.name
95
+
96
+ # Try to auto-exclude the package early. If the autobuild file
97
+ # contained some information that allows us to exclude it now,
98
+ # then let's just do it
99
+ import_next_step(pkg, reverse_dependencies)
100
+ if manifest.excluded?(pkg.name)
101
+ selection.filter_excluded_and_ignored_packages(manifest)
102
+ next
103
+ elsif manifest.ignored?(pkg.name)
104
+ next
105
+ end
106
+
107
+ # If the package has no importer, the source directory must
108
+ # be there
109
+ if !pkg.importer && !File.directory?(pkg.srcdir)
110
+ raise ConfigError.new, "#{pkg.name} has no VCS, but is not checked out in #{pkg.srcdir}"
111
+ end
112
+
113
+ ## COMPLETELY BYPASS RAKE HERE
114
+ # The reason is that the ordering of import/prepare between
115
+ # packages is not important BUT the ordering of import vs.
116
+ # prepare in one package IS important: prepare is the method
117
+ # that takes into account dependencies.
118
+ pkg.import(import_options)
119
+ if pkg.updated?
120
+ updated_packages << pkg.name
121
+ end
122
+ Rake::Task["#{pkg.name}-import"].instance_variable_set(:@already_invoked, true)
123
+ manifest.load_package_manifest(pkg.name)
124
+
125
+ # The package setup mechanisms might have added an exclusion
126
+ # on this package. Handle this.
127
+ if manifest.excluded?(pkg.name)
128
+ mark_exclusion_along_revdeps(pkg.name, reverse_dependencies)
129
+ # Run a filter now, to have errors as early as possible
130
+ selection.filter_excluded_and_ignored_packages(manifest)
131
+ # Delete this package from the current_packages set
132
+ next
133
+ elsif manifest.ignored?(pkg.name)
134
+ next
135
+ end
136
+
137
+ Autoproj.each_post_import_block(pkg) do |block|
138
+ block.call(pkg)
139
+ end
140
+ pkg.update_environment
141
+
142
+ new_packages = import_next_step(pkg, reverse_dependencies)
143
+
144
+ # Excluded dependencies might have caused the package to be
145
+ # excluded as well ... do not add any dependency to the
146
+ # processing queue if it is the case
147
+ if !manifest.excluded?(pkg.name) && options[:recursive]
148
+ package_queue.concat(new_packages.sort_by(&:name))
149
+ end
150
+
151
+ # Verify that everything is still OK with the new
152
+ # exclusions/ignores
153
+ selection.filter_excluded_and_ignored_packages(manifest)
154
+ end
155
+
156
+ # Now run optional dependency resolution. This is done now, as
157
+ # some optional dependencies might have been excluded during the
158
+ # resolution process above
159
+ all_enabled_sources, all_enabled_osdeps =
160
+ Set.new, selection.each_osdep_package_name.to_set
161
+ package_queue = selection.each_source_package_name.to_a
162
+ while !package_queue.empty?
163
+ pkg_name = package_queue.shift
164
+ next if all_enabled_sources.include?(pkg_name)
165
+ all_enabled_sources << pkg_name
166
+
167
+ pkg = manifest.find_autobuild_package(pkg_name)
168
+ packages, osdeps = pkg.partition_optional_dependencies
169
+ packages.each do |pkg_name|
170
+ if !manifest.ignored?(pkg_name) && !manifest.excluded?(pkg_name)
171
+ pkg.depends_on pkg_name
172
+ end
173
+ end
174
+ pkg.os_packages.merge(osdeps)
175
+ all_enabled_osdeps |= pkg.os_packages
176
+
177
+ pkg.prepare if !pkg.disabled?
178
+ Rake::Task["#{pkg.name}-prepare"].instance_variable_set(:@already_invoked, true)
179
+
180
+ if options[:recursive]
181
+ package_queue.concat(pkg.dependencies)
182
+ end
183
+ end
184
+
185
+ if Autoproj.verbose
186
+ Autoproj.message "autoproj: finished importing packages"
187
+ end
188
+
189
+ if options[:warn_about_excluded_packages]
190
+ selection.exclusions.each do |sel, pkg_names|
191
+ pkg_names.sort.each do |pkg_name|
192
+ Autoproj.warn "#{pkg_name}, which was selected for #{sel}, cannot be built: #{manifest.exclusion_reason(pkg_name)}", :bold
193
+ end
194
+ end
195
+ end
196
+ if options[:warn_about_ignored_packages]
197
+ selection.ignores.each do |sel, pkg_names|
198
+ pkg_names.sort.each do |pkg_name|
199
+ Autoproj.warn "#{pkg_name}, which was selected for #{sel}, is ignored", :bold
200
+ end
201
+ end
202
+ end
203
+
204
+ return all_enabled_sources, all_enabled_osdeps
205
+
206
+ ensure
207
+ if ws.config.import_log_enabled? && !updated_packages.empty? && Autoproj::Ops::Snapshot.update_log_available?(manifest)
208
+ failure_message =
209
+ if $!
210
+ " (#{$!.message.split("\n").first})"
211
+ end
212
+ ops = Ops::Snapshot.new(ws.manifest, keep_going: true)
213
+ ops.update_package_import_state(
214
+ "#{$0} #{ARGV.join(" ")}#{failure_message}",
215
+ updated_packages)
216
+ end
217
+ end
218
+ end
219
+ end
220
+ end
221
+
222
+