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.
- checksums.yaml +4 -4
- data/Manifest.txt +9 -0
- data/Rakefile +4 -0
- data/bin/aup +5 -1
- data/bin/autolocate +1 -82
- data/bin/autoproj +6 -56
- data/bin/autoproj-bootstrap +31 -3
- data/bin/autoproj-cache +3 -60
- data/bin/autoproj-clean +1 -1
- data/bin/autoproj-create-set +0 -0
- data/bin/autoproj-doc +1 -1
- data/bin/autoproj-envsh +0 -0
- data/bin/autoproj-list +1 -1
- data/bin/autoproj-locate +17 -16
- data/bin/autoproj-query +0 -0
- data/bin/autoproj-show +0 -0
- data/bin/autoproj-switch-config +23 -0
- data/bin/autoproj-test +2 -2
- data/bin/autoproj_bootstrap +354 -210
- data/bin/autoproj_bootstrap.in +8 -0
- data/bin/autoproj_stress_test +1 -1
- data/lib/autoproj.rb +7 -0
- data/lib/autoproj/autobuild.rb +14 -35
- data/lib/autoproj/build_option.rb +104 -0
- data/lib/autoproj/cmdline.rb +62 -355
- data/lib/autoproj/configuration.rb +161 -0
- data/lib/autoproj/gitorious.rb +31 -20
- data/lib/autoproj/installation_manifest.rb +7 -1
- data/lib/autoproj/manifest.rb +124 -342
- data/lib/autoproj/ops/build.rb +107 -0
- data/lib/autoproj/ops/cache.rb +82 -0
- data/lib/autoproj/ops/configuration.rb +302 -0
- data/lib/autoproj/ops/loader.rb +97 -0
- data/lib/autoproj/ops/main_config_switcher.rb +271 -0
- data/lib/autoproj/ops/tools.rb +54 -0
- data/lib/autoproj/options.rb +26 -178
- data/lib/autoproj/osdeps.rb +49 -9
- data/lib/autoproj/package_set.rb +168 -87
- data/lib/autoproj/system.rb +6 -23
- data/lib/autoproj/variable_expansion.rb +0 -1
- data/lib/autoproj/vcs_definition.rb +23 -0
- data/lib/autoproj/version.rb +1 -1
- 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
|
data/lib/autoproj/gitorious.rb
CHANGED
@@ -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
|
-
"
|
31
|
-
"
|
32
|
-
"
|
33
|
-
|
34
|
-
|
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 =>
|
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
|
-
|
42
|
-
|
53
|
+
value
|
54
|
+
end
|
43
55
|
|
44
56
|
access_mode = Autoproj.user_config(name)
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
Autoproj.change_option("#{name}
|
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
|
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
|
data/lib/autoproj/manifest.rb
CHANGED
@@ -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
|
-
|
134
|
-
|
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(
|
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
|
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(
|
261
|
+
return enum_for(__method__)
|
282
262
|
end
|
283
263
|
|
284
|
-
each_package_set
|
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
|
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
|
-
|
342
|
-
|
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
|
-
#
|
350
|
-
#
|
287
|
+
# Enumerates the version control information for all the package sets
|
288
|
+
# listed directly in the manifest file
|
351
289
|
#
|
352
|
-
#
|
353
|
-
#
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
if
|
360
|
-
|
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.
|
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
|
-
#
|
306
|
+
# Lists all package sets defined in this manifest, including the package
|
307
|
+
# sets that are auto-imported
|
401
308
|
#
|
402
|
-
#
|
403
|
-
|
404
|
-
|
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
|
-
#
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
@package_sets
|
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
|
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
|
461
|
-
#
|
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
|
-
#
|
470
|
-
#
|
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
|
-
|
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
|
-
#
|
574
|
-
|
575
|
-
|
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
|
-
#
|
627
|
-
def
|
628
|
-
|
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
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
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
|
-
#
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
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
|
-
#
|
650
|
-
|
651
|
-
|
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
|
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 =
|
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
|
-
|
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
|
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}
|