autoproj 1.10.2 → 1.11.0.b1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/Manifest.txt +9 -0
  3. data/Rakefile +4 -0
  4. data/bin/aup +5 -1
  5. data/bin/autolocate +1 -82
  6. data/bin/autoproj +6 -56
  7. data/bin/autoproj-bootstrap +31 -3
  8. data/bin/autoproj-cache +3 -60
  9. data/bin/autoproj-clean +1 -1
  10. data/bin/autoproj-create-set +0 -0
  11. data/bin/autoproj-doc +1 -1
  12. data/bin/autoproj-envsh +0 -0
  13. data/bin/autoproj-list +1 -1
  14. data/bin/autoproj-locate +17 -16
  15. data/bin/autoproj-query +0 -0
  16. data/bin/autoproj-show +0 -0
  17. data/bin/autoproj-switch-config +23 -0
  18. data/bin/autoproj-test +2 -2
  19. data/bin/autoproj_bootstrap +354 -210
  20. data/bin/autoproj_bootstrap.in +8 -0
  21. data/bin/autoproj_stress_test +1 -1
  22. data/lib/autoproj.rb +7 -0
  23. data/lib/autoproj/autobuild.rb +14 -35
  24. data/lib/autoproj/build_option.rb +104 -0
  25. data/lib/autoproj/cmdline.rb +62 -355
  26. data/lib/autoproj/configuration.rb +161 -0
  27. data/lib/autoproj/gitorious.rb +31 -20
  28. data/lib/autoproj/installation_manifest.rb +7 -1
  29. data/lib/autoproj/manifest.rb +124 -342
  30. data/lib/autoproj/ops/build.rb +107 -0
  31. data/lib/autoproj/ops/cache.rb +82 -0
  32. data/lib/autoproj/ops/configuration.rb +302 -0
  33. data/lib/autoproj/ops/loader.rb +97 -0
  34. data/lib/autoproj/ops/main_config_switcher.rb +271 -0
  35. data/lib/autoproj/ops/tools.rb +54 -0
  36. data/lib/autoproj/options.rb +26 -178
  37. data/lib/autoproj/osdeps.rb +49 -9
  38. data/lib/autoproj/package_set.rb +168 -87
  39. data/lib/autoproj/system.rb +6 -23
  40. data/lib/autoproj/variable_expansion.rb +0 -1
  41. data/lib/autoproj/vcs_definition.rb +23 -0
  42. data/lib/autoproj/version.rb +1 -1
  43. metadata +17 -7
@@ -0,0 +1,161 @@
1
+ module Autoproj
2
+ # Class that does the handling of configuration options as well as
3
+ # loading/saving on disk
4
+ class Configuration
5
+ # Set of currently known options
6
+ #
7
+ # These are the values that are going to be saved on disk. Use
8
+ # {override} to change a value without changing the saved configuration
9
+ # file.
10
+ attr_reader :config
11
+ # Set of overriden option values that won't get written to file
12
+ attr_reader :overrides
13
+ # Set of options that have been declared with {declare}
14
+ attr_reader :declared_options
15
+ # The options that have already been shown to the user
16
+ attr_reader :displayed_options
17
+
18
+ def initialize
19
+ @config = Hash.new
20
+ @overrides = Hash.new
21
+ @declared_options = Hash.new
22
+ @displayed_options = Hash.new
23
+ end
24
+
25
+ # Deletes the current value for an option
26
+ #
27
+ # The user will be asked for a new value next time the option is needed
28
+ #
29
+ # @param [String] the option name
30
+ # @return the deleted value
31
+ def reset(name)
32
+ config.delete(name)
33
+ end
34
+
35
+ # Sets a configuration option
36
+ #
37
+ # @param [String] key the option name
38
+ # @param [Object] value the option value
39
+ # @param [Boolean] user_validated if true, autoproj will not ask the
40
+ # user about this value next time it is needed. Otherwise, it will be
41
+ # asked about it, the new value being used as default
42
+ def set(key, value, user_validated = false)
43
+ config[key] = [value, user_validated]
44
+ end
45
+
46
+ # Override a known option value
47
+ #
48
+ # The new value will not be saved to disk, unlike with {set}
49
+ def override(option_name, value)
50
+ overrides[option_name] = value
51
+ end
52
+
53
+ # Tests whether a value is set for the given option name
54
+ #
55
+ # @return [Boolean]
56
+ def has_value_for?(name)
57
+ config.has_key?(name) || overrides.has_key?(name)
58
+ end
59
+
60
+ # Get the value for a given option
61
+ def get(key)
62
+ if overrides.has_key?(key)
63
+ return overrides[key]
64
+ end
65
+
66
+ value, validated = config[key]
67
+ if value.nil? || (declared?(key) && !validated)
68
+ value = configure(key)
69
+ else
70
+ if declared?(key) && (displayed_options[key] != value)
71
+ doc = declared_options[key].short_doc
72
+ if doc[-1, 1] != "?"
73
+ doc = "#{doc}:"
74
+ end
75
+ Autoproj.message " #{doc} #{value}"
76
+ displayed_options[key] = value
77
+ end
78
+ value
79
+ end
80
+ end
81
+
82
+ # Returns the option's name-value pairs for the options that do not
83
+ # require user input
84
+ def validated_values
85
+ config.inject(Hash.new) do |h, (k, v)|
86
+ h[k] =
87
+ if overrides.has_key?(k) then overrides[k]
88
+ elsif v.last || !declared?(k) then v.first
89
+ end
90
+ h
91
+ end
92
+ end
93
+
94
+ # Declare an option
95
+ #
96
+ # This declares a given option, thus allowing to ask the user about it
97
+ #
98
+ # @param [String] name the option name
99
+ # @param [String] type the option type (can be 'boolean' or 'string')
100
+ # @option options [String] :short_doc the one-line documentation string
101
+ # that is displayed when the user does not have to be queried. It
102
+ # defaults to the first line of :doc if not given
103
+ # @option options [String] :doc the full option documentation. It is
104
+ # displayed to the user when he is explicitly asked about the option's
105
+ # value
106
+ # @option options [Object] :default the default value this option should
107
+ # take
108
+ # @option options [Array] :possible_values list of possible values (only
109
+ # if the option type is 'string')
110
+ # @option options [Boolean] :lowercase (false) whether the user's input
111
+ # should be converted to lowercase before it gets validated / saved.
112
+ # @option options [Boolean] :uppercase (false) whether the user's input
113
+ # should be converted to uppercase before it gets validated / saved.
114
+ def declare(name, type, options, &validator)
115
+ declared_options[name] = BuildOption.new(name, type, options, validator)
116
+ end
117
+
118
+ # Checks if an option exists
119
+ # @return [Boolean]
120
+ def declared?(name)
121
+ declared_options.has_key?(name)
122
+ end
123
+
124
+ # Configures a given option by asking the user about its desired value
125
+ #
126
+ # @return [Object] the new option value
127
+ # @raise ConfigError if the option is not declared
128
+ def configure(option_name)
129
+ if opt = declared_options[option_name]
130
+ if current_value = config[option_name]
131
+ current_value = current_value.first
132
+ end
133
+ value = opt.ask(current_value)
134
+ config[option_name] = [value, true]
135
+ displayed_options[option_name] = value
136
+ value
137
+ else
138
+ raise ConfigError.new, "undeclared option '#{option_name}'"
139
+ end
140
+ end
141
+
142
+ def load(path, reconfigure = false)
143
+ if h = YAML.load(File.read(path))
144
+ h.each do |key, value|
145
+ set(key, value, !reconfigure)
146
+ end
147
+ end
148
+ end
149
+
150
+ def save(path)
151
+ File.open(path, "w") do |io|
152
+ h = Hash.new
153
+ config.each do |key, value|
154
+ h[key] = value.first
155
+ end
156
+
157
+ io.write YAML.dump(h)
158
+ end
159
+ end
160
+ end
161
+ end
@@ -24,33 +24,44 @@ module Autoproj
24
24
  :git_url => "git://#{base_url}",
25
25
  :http_url => "https://git.#{base_url}",
26
26
  :ssh_url => "git@#{base_url}:",
27
- :fallback_to_http => true
27
+ :fallback_to_http => true,
28
+ :default => 'git,ssh'
28
29
 
29
30
  gitorious_long_doc = [
30
- "Access method to import data from #{base_url} (git, http or ssh)",
31
- "Use 'ssh' only if you have an account there. Note that",
32
- "ssh will always be used to push to the repositories, this is",
33
- "only to get data from the server. Therefore, we advise to use",
34
- "'git' as it is faster than ssh and better than http"]
31
+ "How should I interact with #{base_url} (git, http or ssh)",
32
+ "If you give two values, comma-separated, the first one will be",
33
+ "used for pulling and the second one for pushing"]
34
+
35
+ access_methods = Hash[
36
+ 'git' => 'git,ssh',
37
+ 'ssh' => 'ssh,ssh',
38
+ 'http' => 'http,http']
35
39
 
36
40
  configuration_option name, 'string',
37
- :default => "git",
38
- :values => ["http", "ssh"],
41
+ :default => options[:default],
39
42
  :doc => gitorious_long_doc do |value|
43
+ if value =~ /,/
44
+ value.split(',').each do |method|
45
+ if !access_methods.has_key?(method)
46
+ raise Autoproj::InputError, "#{method} is not a known access method"
47
+ end
48
+ end
49
+ elsif !access_methods.has_key?(value)
50
+ raise Autoproj::InputError, "#{value} is not a known access method"
51
+ end
40
52
 
41
- value
42
- end
53
+ value
54
+ end
43
55
 
44
56
  access_mode = Autoproj.user_config(name)
45
- if access_mode == "git"
46
- Autoproj.change_option("#{name}_ROOT", options[:git_url])
47
- Autoproj.change_option("#{name}_PUSH_ROOT", options[:ssh_url])
48
- elsif access_mode == "http"
49
- Autoproj.change_option("#{name}_ROOT", options[:http_url])
50
- Autoproj.change_option("#{name}_PUSH_ROOT", options[:http_url])
51
- elsif access_mode == "ssh"
52
- Autoproj.change_option("#{name}_ROOT", options[:ssh_url])
53
- Autoproj.change_option("#{name}_PUSH_ROOT", options[:ssh_url])
57
+ access_mode = access_methods[access_mode] || access_mode
58
+ pull, push = access_mode.split(',')
59
+ [[pull, "_ROOT"], [push, "_PUSH_ROOT"]].each do |method, var_suffix|
60
+ url = if method == "git" then options[:git_url]
61
+ elsif method == "http" then options[:http_url]
62
+ elsif method == "ssh" then options[:ssh_url]
63
+ end
64
+ Autoproj.change_option("#{name}#{var_suffix}", url)
54
65
  end
55
66
 
56
67
  Autoproj.add_source_handler name.downcase do |url, vcs_options|
@@ -68,5 +79,5 @@ module Autoproj
68
79
  end
69
80
 
70
81
  Autoproj.gitorious_server_configuration('GITORIOUS', 'gitorious.org')
71
- Autoproj.gitorious_server_configuration('GITHUB', 'github.com', :http_url => 'https://github.com')
82
+ Autoproj.gitorious_server_configuration('GITHUB', 'github.com', :http_url => 'https://github.com', :default => 'http,ssh')
72
83
 
@@ -3,13 +3,19 @@ module Autoproj
3
3
  class InstallationManifest
4
4
  Package = Struct.new :name, :srcdir, :prefix
5
5
 
6
+ DEFAULT_MANIFEST_NAME = ".autoproj-installation-manifest"
7
+
6
8
  attr_reader :path
7
9
  attr_reader :packages
8
10
  def initialize(path)
9
11
  @path = path
10
12
  end
11
13
 
12
- def load(path)
14
+ def default_manifest_path
15
+ File.join(path, DEFAULT_MANIFEST_NAME)
16
+ end
17
+
18
+ def load(path = default_manifest_path)
13
19
  @packages = CSV.read(path).map do |row|
14
20
  Package.new(*row)
15
21
  end
@@ -28,37 +28,18 @@ module Autoproj
28
28
  # The Manifest class represents the information included in the main
29
29
  # manifest file, and allows to manipulate it
30
30
  class Manifest
31
- # Data structure used to use autobuild importers without a package, to
32
- # import configuration data.
33
- #
34
- # It has to match the interface of Autobuild::Package that is relevant
35
- # for importers
36
- class FakePackage < Autobuild::Package
37
- attr_reader :srcdir
38
- attr_reader :importer
39
-
40
- # Used by the autobuild importers
41
- attr_accessor :updated
42
-
43
- def initialize(text_name, srcdir, importer = nil)
44
- super(text_name)
45
- @srcdir = srcdir
46
- @importer = importer
47
- @@packages.delete(text_name)
48
- end
49
-
50
- def import
51
- importer.import(self,Manifest.only_local_updates)
52
- end
53
-
54
- def add_stat(*args)
55
- end
56
- end
57
-
58
31
  # The set of packages that are selected by the user, either through the
59
32
  # manifest file or through the command line, as a set of package names
60
33
  attr_accessor :explicit_selection
61
34
 
35
+ # Set the package sets that are available on this manifest
36
+ #
37
+ # This is set externally at loading time. {load_and_update_package_sets}
38
+ # can do it as well
39
+ #
40
+ # @return [Array<PackageSet>]
41
+ attr_writer :package_sets
42
+
62
43
  # Returns true if +pkg_name+ has been explicitely selected
63
44
  def explicitly_selected_package?(pkg_name)
64
45
  explicit_selection && explicit_selection.include?(pkg_name)
@@ -130,16 +111,16 @@ module Autoproj
130
111
 
131
112
  attr_reader :metapackages
132
113
 
133
- class << self
134
- #Set to true if this manifest should only do local updates through the Autobuild::Importer
135
- attr_accessor :only_local_updates
136
- end
114
+ # The VCS object for the main configuration itself
115
+ attr_reader :vcs
137
116
 
138
117
  def initialize
139
118
  @file = nil
140
119
  @data = Hash.new
141
120
  @packages = Hash.new
142
121
  @package_manifests = Hash.new
122
+ @package_sets = []
123
+
143
124
  @automatic_exclusions = Hash.new
144
125
  @constants_definitions = Hash.new
145
126
  @disabled_imports = Set.new
@@ -149,7 +130,6 @@ module Autoproj
149
130
  @ignored_os_dependencies = Set.new
150
131
  @reused_installations = Array.new
151
132
  @ignored_packages = Set.new
152
- Manifest::only_local_updates = false
153
133
 
154
134
  @constant_definitions = Hash.new
155
135
  if Autoproj.has_config_key?('manifest_source')
@@ -252,7 +232,7 @@ module Autoproj
252
232
  # Lists the autobuild files that are in the package sets we know of
253
233
  def each_autobuild_file(source_name = nil, &block)
254
234
  if !block_given?
255
- return enum_for(:each_source_file, source_name)
235
+ return enum_for(__method__, source_name)
256
236
  end
257
237
 
258
238
  # This looks very inefficient, but it is because source names are
@@ -261,7 +241,7 @@ module Autoproj
261
241
  #
262
242
  # And honestly I don't think someone will have 20 000 package sets
263
243
  done_something = false
264
- each_package_set(false) do |source|
244
+ each_package_set do |source|
265
245
  next if source_name && source.name != source_name
266
246
  done_something = true
267
247
 
@@ -278,10 +258,10 @@ module Autoproj
278
258
  # Yields each osdeps definition files that are present in our sources
279
259
  def each_osdeps_file
280
260
  if !block_given?
281
- return enum_for(:each_source_file)
261
+ return enum_for(__method__)
282
262
  end
283
263
 
284
- each_package_set(false) do |source|
264
+ each_package_set do |source|
285
265
  Dir.glob(File.join(source.local_dir, "*.osdeps")).each do |file|
286
266
  yield(source, file)
287
267
  end
@@ -293,130 +273,62 @@ module Autoproj
293
273
  each_remote_source(false).any? { true }
294
274
  end
295
275
 
296
- # True if calling update_remote_sources will actually do anything
297
- def should_update_remote_sources
298
- if Autobuild.do_update
299
- return true
300
- end
301
-
302
- each_remote_source(false) do |source|
303
- if !File.directory?(source.local_dir)
304
- return true
305
- end
306
- end
307
- false
308
- end
309
-
310
276
  # Like #each_package_set, but filters out local package sets
311
- def each_remote_package_set(load_description = true)
312
- if !block_given?
313
- enum_for(:each_remote_package_set, load_description)
314
- else
315
- each_package_set(load_description) do |source|
316
- if !source.local?
317
- yield(source)
318
- end
319
- end
320
- end
321
- end
322
-
323
- def each_remote_source(*args, &block)
324
- each_remote_package_set(*args, &block)
325
- end
326
-
327
- # Helper method for #each_package_set
328
- def enumerate_package_set(pkg_set, explicit_sets, all_sets) # :nodoc:
329
- if @disabled_imports.include?(pkg_set.name)
330
- pkg_set.auto_imports = false
331
- end
332
-
333
- result = []
334
- if pkg_set.auto_imports?
335
- pkg_set.each_imported_set do |imported_set|
336
- if explicit_sets.any? { |src| src.vcs == imported_set.vcs } ||
337
- all_sets.any? { |src| src.vcs == imported_set.vcs }
338
- next
339
- end
277
+ def each_remote_package_set
278
+ return enum_for(__method__) if !block_given?
340
279
 
341
- all_sets << imported_set
342
- result.concat(enumerate_package_set(imported_set, explicit_sets, all_sets))
280
+ each_package_set do |pkg_set|
281
+ if !pkg_set.local?
282
+ yield(pkg_set)
343
283
  end
344
284
  end
345
- result << pkg_set
346
- result
347
285
  end
348
286
 
349
- # call-seq:
350
- # each_package_set { |pkg_set| ... }
287
+ # Enumerates the version control information for all the package sets
288
+ # listed directly in the manifest file
351
289
  #
352
- # Lists all package sets defined in this manifest, by yielding a
353
- # PackageSet object that describes it.
354
- def each_package_set(load_description = true, &block)
355
- if !block_given?
356
- return enum_for(:each_package_set, load_description)
357
- end
358
-
359
- if @package_sets
360
- if load_description
361
- @package_sets.each do |src|
362
- if !src.source_definition
363
- src.load_description_file
364
- end
365
- end
366
- end
367
- return @package_sets.each(&block)
368
- end
369
-
370
- explicit_sets = (data['package_sets'] || []).map do |spec|
290
+ # @yieldparam [VCSDefinition] vcs the package set VCS object
291
+ # @yieldparam [Hash] options additional import options
292
+ # @options options [Boolean] :auto_update (true) if true, the set of
293
+ # package sets declared as imports in package set's source.yml file
294
+ # will be auto-imported by autoproj, otherwise they won't
295
+ # @return [nil]
296
+ def each_raw_explicit_package_set
297
+ return enum_for(__method__) if !block_given?
298
+ (data['package_sets'] || []).map do |spec|
371
299
  Autoproj.in_file(self.file) do
372
- PackageSet.from_spec(self, spec, load_description)
300
+ yield(*PackageSet.resolve_definition(self, spec))
373
301
  end
374
302
  end
375
-
376
- all_sets = Array.new
377
- explicit_sets.each do |pkg_set|
378
- all_sets.concat(enumerate_package_set(pkg_set, explicit_sets, all_sets + [pkg_set]))
379
- end
380
-
381
- # Now load the local source
382
- local = LocalPackageSet.new(self)
383
- if load_description
384
- local.load_description_file
385
- else
386
- local.load_minimal
387
- end
388
- if !load_description || !local.empty?
389
- all_sets << local
390
- end
391
-
392
- if load_description
393
- all_sets.each(&:load_description_file)
394
- else
395
- all_sets.each(&:load_minimal)
396
- end
397
- all_sets.each(&block)
303
+ nil
398
304
  end
399
305
 
400
- # DEPRECATED. For backward-compatibility only
306
+ # Lists all package sets defined in this manifest, including the package
307
+ # sets that are auto-imported
401
308
  #
402
- # use #each_package_set instead
403
- def each_source(*args, &block)
404
- each_package_set(*args, &block)
309
+ # Note that this can be called only after the package sets got loaded
310
+ # with {load_package_sets}
311
+ #
312
+ # @yieldparam [PackageSet]
313
+ def each_package_set(&block)
314
+ @package_sets.each(&block)
315
+ end
316
+
317
+ # Load the package set information
318
+ def load_and_update_package_sets
319
+ Ops::Configuration.new(self, Ops.loader).load_and_update_package_sets
405
320
  end
406
321
 
322
+ # Returns a package set that is used by autoproj for its own purposes
407
323
  def local_package_set
408
324
  each_package_set.find { |s| s.kind_of?(LocalPackageSet) }
409
325
  end
410
326
 
411
- # Save the currently known package sets. After this call,
412
- # #each_package_set will always return the same set regardless of
413
- # changes on the manifest's data structures
414
- def cache_package_sets
415
- @package_sets = each_package_set(false).to_a
416
- @package_sets.each do |pkg_set|
417
- @metapackages[pkg_set.name] ||= Metapackage.new(pkg_set.name)
418
- @metapackages["#{pkg_set.name}.all"] ||= Metapackage.new("#{pkg_set.name}.all")
419
- end
327
+ # Registers a new package set
328
+ def register_package_set(pkg_set)
329
+ metapackage(pkg_set.name)
330
+ metapackage("#{pkg_set.name}.all")
331
+ @package_sets << pkg_set
420
332
  end
421
333
 
422
334
  # Register a new package
@@ -430,26 +342,48 @@ module Autoproj
430
342
  @metapackages["#{pkg.package_set.name}.all"].add(pkg.autobuild)
431
343
  end
432
344
 
345
+ # Returns the package set that defines a package
346
+ #
347
+ # @param [String] package_name the package name
348
+ # @return [PackageSet] the package set
349
+ # @raise ArgumentError if package_name is not the name of a known
350
+ # package
433
351
  def definition_package_set(package_name)
434
352
  if pkg_def = @packages[package_name]
435
353
  pkg_def.package_set
354
+ else raise ArgumentError, "no package called #{package_name}"
436
355
  end
437
356
  end
438
357
 
358
+ # @deprecated use {definition_package_set} instead
439
359
  def definition_source(package_name)
440
360
  definition_package_set(package_name)
441
361
  end
362
+
363
+ # Returns the full path to the file that defines a package
364
+ #
365
+ # @param [String] package_name the package name
366
+ # @return [String] the package set
367
+ # @raise ArgumentError if package_name is not the name of a known
368
+ # package
442
369
  def definition_file(package_name)
443
370
  if pkg_def = @packages[package_name]
444
371
  pkg_def.file
372
+ else raise ArgumentError, "no package called #{package_name}"
445
373
  end
446
374
  end
447
375
 
376
+ def find_package(name)
377
+ packages[name]
378
+ end
379
+
448
380
  def package(name)
449
381
  packages[name]
450
382
  end
451
383
 
452
- # Lists all defined packages as PackageDefinition objects
384
+ # Lists all defined packages
385
+ #
386
+ # @yieldparam [PackageDefinition] pkg
453
387
  def each_package_definition(&block)
454
388
  if !block_given?
455
389
  return enum_for(:each_package_definition)
@@ -457,216 +391,53 @@ module Autoproj
457
391
  packages.each_value(&block)
458
392
  end
459
393
 
460
- # Lists all defined autobuild packages as instances of
461
- # Autobuild::Package and its subclasses
394
+ # Lists the autobuild objects for all defined packages
395
+ #
396
+ # @yieldparam [Autobuild::Package] pkg
462
397
  def each_autobuild_package
463
- if !block_given?
464
- return enum_for(:each_package)
465
- end
398
+ return enum_for(__method__) if !block_given?
466
399
  packages.each_value { |pkg| yield(pkg.autobuild) }
467
400
  end
468
401
 
469
- # DEPRECATED: use either #each_autobuild_package and
470
- # #each_package_definition
471
- def each_package(&block)
472
- each_autobuild_package(&block)
473
- end
474
-
475
- # The VCS object for the main configuration itself
476
- attr_reader :vcs
477
-
478
- def each_configuration_source
479
- if !block_given?
480
- return enum_for(:each_configuration_source)
481
- end
482
-
483
- if vcs
484
- yield(vcs, "autoproj main configuration", Autoproj.config_dir)
485
- end
486
-
487
- each_remote_source(false) do |source|
488
- yield(source.vcs, source.name || source.vcs.url, source.local_dir)
489
- end
490
- self
491
- end
492
-
493
- # Creates an autobuild package whose job is to allow the import of a
494
- # specific repository into a given directory.
495
- #
496
- # +vcs+ is the VCSDefinition file describing the repository, +text_name+
497
- # the name used when displaying the import progress, +pkg_name+ the
498
- # internal name used to represent the package and +into+ the directory
499
- # in which the package should be checked out.
402
+ # @deprecated use Ops::Tools.create_autobuild_package or include
403
+ # Ops::Tools into your class to get it as instance method
500
404
  def self.create_autobuild_package(vcs, text_name, into)
501
- importer = vcs.create_autobuild_importer
502
- return if !importer # updates have been disabled by using the 'none' type
503
-
504
- FakePackage.new(text_name, into, importer)
505
-
506
- rescue Autobuild::ConfigException => e
507
- raise ConfigError.new, "cannot import #{name}: #{e.message}", e.backtrace
508
- end
509
-
510
- # Imports or updates a source (remote or otherwise).
511
- #
512
- # See create_autobuild_package for informations about the arguments.
513
- def self.update_package_set(vcs, text_name, into)
514
- fake_package = create_autobuild_package(vcs, text_name, into)
515
- if other_root = CmdLine.update_from
516
- # Define a package in the installation manifest that points to
517
- # the desired folder in other_root
518
- relative_path = Pathname.new(into).
519
- relative_path_from(Pathname.new(Autoproj.root_dir)).to_s
520
- other_dir = File.join(other_root.path, relative_path)
521
- if File.directory?(other_dir)
522
- other_root.packages.unshift(
523
- InstallationManifest::Package.new(fake_package.name, other_dir, File.join(other_dir, 'install')))
524
- end
525
-
526
- # Then move the importer there if possible
527
- if fake_package.importer.respond_to?(:pick_from_autoproj_root)
528
- if !fake_package.importer.pick_from_autoproj_root(fake_package, other_root)
529
- fake_package.update = false
530
- end
531
- else
532
- fake_package.update = false
533
- end
534
- end
535
- fake_package.import
536
-
537
- rescue Autobuild::ConfigException => e
538
- raise ConfigError.new, "cannot import #{name}: #{e.message}", e.backtrace
539
- end
540
-
541
- # Updates the main autoproj configuration
542
- def update_yourself
543
- Manifest.update_package_set(vcs, "autoproj main configuration", Autoproj.config_dir)
544
- end
545
-
546
- def update_remote_set(pkg_set, remotes_symlinks_dir = nil)
547
- Manifest.update_package_set(
548
- pkg_set.vcs,
549
- pkg_set.name,
550
- pkg_set.raw_local_dir)
551
-
552
- if remotes_symlinks_dir
553
- pkg_set.load_minimal
554
- symlink_dest = File.join(remotes_symlinks_dir, pkg_set.name)
555
-
556
- # Check if the current symlink is valid, and recreate it if it
557
- # is not
558
- if File.symlink?(symlink_dest)
559
- dest = File.readlink(symlink_dest)
560
- if dest != pkg_set.raw_local_dir
561
- FileUtils.rm_f symlink_dest
562
- Autoproj.create_symlink(pkg_set.raw_local_dir, symlink_dest)
563
- end
564
- else
565
- FileUtils.rm_f symlink_dest
566
- Autoproj.create_symlink(pkg_set.raw_local_dir, symlink_dest)
567
- end
568
-
569
- symlink_dest
570
- end
405
+ Ops::Tools.create_autobuild_package(vcs, text_name, into)
571
406
  end
572
407
 
573
- # Updates all the remote sources in ROOT_DIR/.remotes, as well as the
574
- # symbolic links in ROOT_DIR/autoproj/remotes
575
- def update_remote_package_sets
576
- remotes_symlinks_dir = File.join(Autoproj.config_dir, 'remotes')
577
- FileUtils.mkdir_p remotes_symlinks_dir
578
-
579
- # Iterate on the remote sources, without loading the source.yml
580
- # file (we're not ready for that yet)
581
- #
582
- # Do it iteratively to properly take imports into account, but we
583
- # first unconditionally update all the existing sets to properly
584
- # handle imports that have been removed
585
- updated_sets = Hash.new
586
- known_remotes = []
587
- each_remote_package_set(false) do |pkg_set|
588
- next if !pkg_set.explicit?
589
- if pkg_set.present?
590
- known_remotes << update_remote_set(pkg_set, remotes_symlinks_dir)
591
- updated_sets[pkg_set.repository_id] = pkg_set
592
- end
593
- end
594
-
595
- old_updated_sets = nil
596
- while old_updated_sets != updated_sets
597
- old_updated_sets = updated_sets.dup
598
- each_remote_package_set(false) do |pkg_set|
599
- next if updated_sets.has_key?(pkg_set.repository_id)
600
-
601
- if !pkg_set.explicit?
602
- Autoproj.message " #{pkg_set.imported_from.name}: auto-importing #{pkg_set.name}"
603
- end
604
- known_remotes << update_remote_set(pkg_set, remotes_symlinks_dir)
605
- updated_sets[pkg_set.repository_id] = pkg_set
606
- end
607
- end
608
-
609
- # Check for directories in ROOT_DIR/.remotes that do not map to a
610
- # source repository, and remove them
611
- Dir.glob(File.join(Autoproj.remotes_dir, '*')).each do |dir|
612
- dir = File.expand_path(dir)
613
- if File.directory?(dir) && !updated_sets.values.find { |pkg| pkg.raw_local_dir == dir }
614
- FileUtils.rm_rf dir
615
- end
616
- end
617
-
618
- # Now remove obsolete symlinks
619
- Dir.glob(File.join(remotes_symlinks_dir, '*')).each do |file|
620
- if File.symlink?(file) && !known_remotes.include?(file)
621
- FileUtils.rm_f file
622
- end
623
- end
408
+ # @deprecated use Ops::Configuration#update_main_configuration
409
+ def update_yourself(only_local = false)
410
+ Ops::Configuration.new(self, Ops.loader).update_main_configuration(only_local)
624
411
  end
625
412
 
626
- # DEPRECATED. For backward-compatibility only
627
- def update_remote_sources(*args, &block)
628
- update_remote_package_sets(*args, &block)
413
+ # @deprecated use Ops::Configuration.update_remote_package_set
414
+ def update_remote_set(vcs, only_local = false)
415
+ Ops::Configuration.update_remote_package_set(vcs, only_local)
629
416
  end
630
417
 
631
- def importer_definition_for(package_name, package_source = nil)
632
- if !package_source
633
- package_source = packages.values.
634
- find { |pkg| pkg.autobuild.name == package_name }.
635
- package_set
636
- end
637
-
638
- sources = each_package_set.to_a.dup
418
+ # Compute the VCS definition for a given package
419
+ #
420
+ # @param [String] package_name the name of the package to be resolved
421
+ # @param [PackageSet,nil] package_source the package set that defines the
422
+ # given package, defaults to the package's definition source (as
423
+ # returned by {definition_package_set}) if not given
424
+ # @return [VCSDefinition] the VCS definition object
425
+ def importer_definition_for(package_name, package_source = definition_package_set(package_name))
426
+ vcs = package_source.importer_definition_for(package_name)
427
+ return if !vcs
639
428
 
640
- # Remove sources listed before the package source
641
- while !sources.empty? && sources[0].name != package_source.name
642
- sources.shift
643
- end
644
- package_source = sources.shift
645
- if !package_source
646
- raise InternalError, "cannot find the package set that defines #{package_name}"
429
+ # Get the sets that come *after* the one that defines the package to
430
+ # apply the overrides
431
+ package_sets = each_package_set.to_a.dup
432
+ while !package_sets.empty? && package_sets.first != package_source
433
+ package_sets.shift
647
434
  end
435
+ package_sets.shift
648
436
 
649
- # Get the version control information from the package source. There
650
- # must be one
651
- vcs_spec, raw = Autoproj.in_file package_source.source_file do
652
- package_source.version_control_field(package_name, 'version_control')
437
+ # Then apply the overrides
438
+ package_sets.inject(vcs) do |updated_vcs, pkg_set|
439
+ pkg_set.overrides_for(package_name, updated_vcs)
653
440
  end
654
- return if !vcs_spec
655
-
656
- sources.each do |src|
657
- overrides_spec, raw_additional = src.version_control_field(package_name, 'overrides', false)
658
- raw = raw.concat(raw_additional)
659
- if overrides_spec
660
- vcs_spec = Autoproj.in_file src.source_file do
661
- begin
662
- VCSDefinition.update_raw_vcs_spec(vcs_spec, overrides_spec)
663
- rescue ConfigError => e
664
- raise ConfigError.new, "invalid resulting VCS specification in the overrides section for package #{package_name}: #{e.message}"
665
- end
666
- end
667
- end
668
- end
669
- VCSDefinition.from_raw(vcs_spec, raw)
670
441
  end
671
442
 
672
443
  # Sets up the package importers based on the information listed in
@@ -700,10 +471,18 @@ module Autoproj
700
471
  end
701
472
  end
702
473
 
474
+ # Checks if there is a package with a given name
475
+ #
476
+ # @param [String] name
477
+ # @return [Boolean]
478
+ def has_package?(name)
479
+ packages.has_key?(name)
480
+ end
481
+
703
482
  # Returns true if +name+ is the name of a package set known to this
704
483
  # autoproj installation
705
484
  def has_package_set?(name)
706
- each_package_set(false).find { |set| set.name == name }
485
+ each_package_set.find { |set| set.name == name }
707
486
  end
708
487
 
709
488
  # Returns the PackageSet object for the given package set, or raises
@@ -1046,7 +825,7 @@ module Autoproj
1046
825
  # Returns the package directory for the given package name
1047
826
  def whereis(package_name)
1048
827
  Autoproj.in_file(self.file) do
1049
- set_name = definition_source(package_name).name
828
+ set_name = definition_package_set(package_name).name
1050
829
  actual_layout = normalized_layout
1051
830
  return actual_layout[package_name] || actual_layout[set_name] || '/'
1052
831
  end
@@ -1325,11 +1104,10 @@ module Autoproj
1325
1104
  end
1326
1105
 
1327
1106
  manifest = InstallationManifest.new(dir)
1328
- manifest_file = File.join(dir, ".autoproj-installation-manifest")
1329
- if !File.file?(manifest_file)
1107
+ if !File.file?(manifest.default_manifest_path)
1330
1108
  raise ConfigError.new, "while setting up reuse of #{dir}, the .autoproj-installation-manifest file does not exist. You should probably rerun autoproj envsh in that folder first"
1331
1109
  end
1332
- manifest.load(manifest_file)
1110
+ manifest.load
1333
1111
  @reused_installations << manifest
1334
1112
  manifest.each do |pkg|
1335
1113
  ignore_package pkg.name
@@ -1360,6 +1138,10 @@ module Autoproj
1360
1138
  # @return [OSDependencies]
1361
1139
  # @see load_osdeps_from_package_sets
1362
1140
  attr_accessor :osdeps
1141
+
1142
+ # The configuration file
1143
+ # @return [Configuration]
1144
+ attr_accessor :config
1363
1145
  end
1364
1146
 
1365
1147
  # Load the osdeps files contained in {manifest} into {osdeps}