autoproj 1.13.7 → 2.0.0.b1

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