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
@@ -1,18 +1,44 @@
1
1
  module Autoproj
2
+ # Flattens a hash whose keys are strings and values are either plain values,
3
+ # arrays or hashes
4
+ #
5
+ # The keys in the flattened hash are made hierarchical by appending ".".
6
+ # Array values are ignored.
7
+ #
8
+ # @example
9
+ # h = Hash['test' => 10, 'h' => Hash['value' => '20']]
10
+ # options_to_flat_hash(h)
11
+ # # Hash['test' => '10',
12
+ # # 'h.value' => 20]
13
+ #
14
+ #
15
+ # @param [{[String,Symbol]=>[String,Numeric,Array,Hash]}]
16
+ # @return [{String=>String}]
17
+ def self.flatten_recursive_hash(hash, prefix = "")
18
+ result = Hash.new
19
+ hash.each do |k, v|
20
+ if v.kind_of?(Hash)
21
+ result.merge!(flatten_recursive_hash(v, "#{prefix}#{k}."))
22
+ elsif !v.respond_to?(:to_ary)
23
+ result["#{prefix}#{k}"] = v.to_s
24
+ end
25
+ end
26
+ result
27
+ end
28
+
2
29
  # Expand build options in +value+.
3
30
  #
4
31
  # The method will expand in +value+ patterns of the form $NAME, replacing
5
32
  # them with the corresponding build option.
6
33
  def self.expand_environment(value)
34
+ return value if !contains_expansion?(value)
35
+
7
36
  # Perform constant expansion on the defined environment variables,
8
37
  # including the option set
9
- options = Autoproj.option_set
10
- options.each_key do |k|
11
- options[k] = options[k].to_s
12
- end
38
+ options = flatten_recursive_hash(config.validated_values)
13
39
 
14
40
  loop do
15
- new_value = Autoproj.single_expansion(value, options)
41
+ new_value = single_expansion(value, options)
16
42
  if new_value == value
17
43
  break
18
44
  else
@@ -45,7 +71,7 @@ module Autoproj
45
71
  end
46
72
 
47
73
  if !(value = definitions[constant_name])
48
- if !(value = Autoproj.user_config(constant_name))
74
+ if !(value = config.get(constant_name))
49
75
  if !block_given? || !(value = yield(constant_name))
50
76
  raise ArgumentError, "cannot find a definition for $#{constant_name}"
51
77
  end
@@ -6,20 +6,32 @@ module Autoproj
6
6
  attr_reader :url
7
7
  attr_reader :options
8
8
 
9
+ # This VCSDefinition history, i.e. the list of VCSDefinition objects
10
+ # that led to this one by means of calls to {#update}
11
+ attr_reader :history
9
12
  # The original spec in hash form. Set if this VCSDefinition object has
10
13
  # been created using VCSDefinition.from_raw
11
14
  attr_reader :raw
12
15
 
13
- def initialize(type, url, options, raw = nil)
16
+ def initialize(type, url, vcs_options, options = Hash.new)
14
17
  if raw && !raw.respond_to?(:to_ary)
15
18
  raise ArgumentError, "wrong format for the raw field (#{raw.inspect})"
16
19
  end
20
+ if !options.kind_of?(Hash)
21
+ options = Hash[raw: options]
22
+ end
23
+ if vcs_options[:raw]
24
+ raise
25
+ end
26
+ options = validate_options options, from: nil, raw: nil, history: nil
17
27
 
18
- @type, @url, @options = type, url, options
28
+ @type, @url, @options = type, url, vcs_options
19
29
  if type != "none" && type != "local" && !Autobuild.respond_to?(type)
20
30
  raise ConfigError.new, "version control #{type} is unknown to autoproj"
21
31
  end
22
- @raw = raw
32
+
33
+ @history = (options[:history] || Array.new) + [[options[:from], self]]
34
+ @raw = options[:raw] || [[options[:from], to_hash]]
23
35
  end
24
36
 
25
37
  def local?
@@ -34,15 +46,24 @@ module Autoproj
34
46
  # the updated definition
35
47
  #
36
48
  # @return [VCSDefinition]
37
- def update(spec, new_raw_entry)
49
+ def update(spec, options = Hash.new)
50
+ if !options.kind_of?(Hash)
51
+ options = Hash[raw: options]
52
+ end
53
+ from, options = filter_options options, from: nil, raw: nil
54
+ from = from[:from]
38
55
  new = self.class.vcs_definition_to_hash(spec)
39
- if new.has_key?(:type) && (type != new[:type])
40
- # The type changed. We replace the old definition by the new one
41
- # completely
42
- self.class.from_raw(new, new_raw_entry)
43
- else
44
- self.class.from_raw(to_hash.merge(new), raw + new_raw_entry)
56
+ new_raw = options[:raw] || [[from, spec]]
57
+ new_history = Array.new
58
+
59
+ # If the type changed, we replace the old definition by the new one
60
+ # completely. Otherwise, we append it to the current one
61
+ if !new.has_key?(:type) || (type == new[:type])
62
+ new = to_hash.merge(new)
63
+ new_raw = self.raw + new_raw
64
+ new_history = self.history
45
65
  end
66
+ self.class.from_raw(new, from: from, history: new_history, raw: new_raw)
46
67
  end
47
68
 
48
69
  # Updates the VCS specification +old+ by the information contained in
@@ -50,7 +71,7 @@ module Autoproj
50
71
  #
51
72
  # Both +old+ and +new+ are supposed to be in hash form. It is assumed
52
73
  # that +old+ has already been normalized by a call to
53
- # Autoproj.vcs_definition_to_hash. +new+ can be in "raw" form.
74
+ # {.vcs_definition_to_hash}. +new+ can be in "raw" form.
54
75
  def self.update_raw_vcs_spec(old, new)
55
76
  new = vcs_definition_to_hash(new)
56
77
  if new.has_key?(:type) && (old[:type] != new[:type])
@@ -131,21 +152,32 @@ module Autoproj
131
152
  spec
132
153
  end
133
154
 
134
- # Autoproj configuration files accept VCS definitions in three forms:
155
+ # Converts a 'raw' VCS representation to a normalized hash.
156
+ #
157
+ # The raw definition can have three forms:
135
158
  # * as a plain string, which is a relative/absolute path
136
159
  # * as a plain string, which is a vcs_type:url string
137
160
  # * as a hash
138
161
  #
139
- # This method returns the VCSDefinition object matching one of these
140
- # specs. It raises ConfigError if there is no type and/or url
141
- def self.from_raw(spec, raw_spec = [[nil, spec]])
162
+ # @return [VCSDefinition]
163
+ # @raise ArgumentError if the raw specification does not match an
164
+ # expected format
165
+ def self.from_raw(spec, options = Hash.new)
166
+ if !options.kind_of?(Hash)
167
+ options = Hash[raw: options]
168
+ end
169
+ options = validate_options options, from: nil, raw: nil, history: nil
170
+ from = options[:from]
171
+ history = options[:history] || Array.new
172
+ raw = options[:raw] || [[from, spec]]
173
+
142
174
  spec = vcs_definition_to_hash(spec)
143
175
  if !(spec[:type] && (spec[:type] == 'none' || spec[:url]))
144
176
  raise ConfigError.new, "the source specification #{spec.inspect} misses either the VCS type or an URL"
145
177
  end
146
178
 
147
179
  spec, vcs_options = Kernel.filter_options spec, :type => nil, :url => nil
148
- return VCSDefinition.new(spec[:type], spec[:url], vcs_options, raw_spec)
180
+ return VCSDefinition.new(spec[:type], spec[:url], vcs_options, from: from, history: history, raw: raw)
149
181
  end
150
182
 
151
183
  def ==(other_vcs)
@@ -192,7 +224,15 @@ module Autoproj
192
224
  return if !needs_import?
193
225
 
194
226
  url = VCSDefinition.to_absolute_url(self.url)
195
- Autobuild.send(type, url, options)
227
+ importer = Autobuild.send(type, url, options)
228
+ if importer.respond_to?(:declare_alternate_repository)
229
+ history.each do |from, vcs|
230
+ next if !from || from.main?
231
+ url = VCSDefinition.to_absolute_url(vcs.url)
232
+ importer.declare_alternate_repository(from.name, url, vcs.options)
233
+ end
234
+ end
235
+ importer
196
236
  end
197
237
 
198
238
  # Returns a pretty representation of this VCS definition
@@ -1,3 +1,3 @@
1
1
  module Autoproj
2
- VERSION = "1.13.7"
2
+ VERSION = "2.0.0.b1"
3
3
  end
@@ -0,0 +1,550 @@
1
+ require 'autoproj/ops/import'
2
+
3
+ module Autoproj
4
+ class Workspace < Ops::Loader
5
+ attr_reader :root_dir
6
+
7
+ attr_reader :config
8
+ attr_reader :env
9
+ attr_reader :manifest
10
+ attr_reader :loader
11
+
12
+ def initialize(root_dir)
13
+ @root_dir = root_dir
14
+ @loader = loader
15
+ @env = Environment.new
16
+ @manifest = Manifest.new
17
+ Autobuild.env = nil
18
+ env.prepare(root_dir)
19
+
20
+ super(root_dir)
21
+ end
22
+
23
+ def self.autoproj_current_root
24
+ if env = ENV['AUTOPROJ_CURRENT_ROOT']
25
+ if !env.empty?
26
+ env
27
+ end
28
+ end
29
+ end
30
+
31
+ def self.from_pwd
32
+ from_dir(Dir.pwd)
33
+ end
34
+
35
+ def self.from_dir(dir)
36
+ if path = find_root_dir(dir)
37
+ # Make sure that the currently loaded env.sh is actually us
38
+ env = autoproj_current_root
39
+ if env && env != path
40
+ raise UserError, "the current environment is for #{env}, but you are in #{path}, make sure you are loading the right #{ENV_FILENAME} script !"
41
+ end
42
+ Workspace.new(path)
43
+ else
44
+ raise UserError, "not in a Autoproj installation"
45
+ end
46
+ end
47
+
48
+ def self.from_environment
49
+ if path = (find_root_dir || autoproj_current_root)
50
+ from_dir(path)
51
+ else
52
+ raise UserError, "not in an Autoproj installation, and no env.sh has been loaded so far"
53
+ end
54
+ end
55
+
56
+ def self.find_root_dir(base_dir = Dir.pwd)
57
+ path = Pathname.new(base_dir)
58
+ while !path.root?
59
+ if (path + "autoproj" + 'manifest').file?
60
+ break
61
+ end
62
+ path = path.parent
63
+ end
64
+
65
+ if path.root?
66
+ return
67
+ end
68
+
69
+ result = path.to_s
70
+
71
+ # I don't know if this is still useful or not ... but it does not hurt
72
+ #
73
+ # Preventing backslashed in path, that might be confusing on some path compares
74
+ if Autobuild.windows?
75
+ result = result.gsub(/\\/,'/')
76
+ end
77
+ result
78
+ end
79
+
80
+ def osdeps
81
+ manifest.osdeps
82
+ end
83
+
84
+ def load(*args)
85
+ set_as_main_workspace
86
+ flag, Autoproj.warn_deprecated_level = Autoproj.warn_deprecated_level, 1
87
+ super
88
+ ensure
89
+ Autoproj.warn_deprecated_level = flag
90
+ end
91
+
92
+ # Returns the configuration directory for this autoproj installation.
93
+ #
94
+ # @return [String]
95
+ def config_dir
96
+ File.join(root_dir, 'autoproj')
97
+ end
98
+
99
+ # Return the directory in which remote package set definition should be
100
+ # checked out
101
+ def remotes_dir
102
+ File.join(root_dir, ".remotes")
103
+ end
104
+
105
+ # (see Configuration#prefix_dir)
106
+ def prefix_dir
107
+ File.expand_path(config.prefix_dir, root_dir)
108
+ end
109
+
110
+ # Change {prefix_dir}
111
+ def prefix_dir=(path)
112
+ config.set 'prefix', path, true
113
+ end
114
+
115
+ # (see Configuration#build_dir)
116
+ def build_dir
117
+ config.build_dir
118
+ end
119
+
120
+ # Change {#build_dir}
121
+ def build_dir=(path)
122
+ config.set 'build', path, true
123
+ end
124
+
125
+ def log_dir
126
+ File.join(prefix_dir, 'log')
127
+ end
128
+
129
+ OVERRIDES_DIR = "overrides.d"
130
+
131
+ # Returns the directory containing overrides files
132
+ #
133
+ # @return [String]
134
+ def overrides_dir
135
+ File.join(config_dir, OVERRIDES_DIR)
136
+ end
137
+
138
+ def load_config(reconfigure = false)
139
+ config_path = File.join(config_dir, 'config.yml')
140
+ @config = Configuration.new(config_path)
141
+ if File.file?(config_path)
142
+ config.load(reconfigure: reconfigure)
143
+ manifest.vcs = VCSDefinition.from_raw(config.get('manifest_source', nil))
144
+ end
145
+ end
146
+
147
+ def load_manifest
148
+ manifest_path = File.join(config_dir, 'manifest')
149
+ if File.exists?(manifest_path)
150
+ manifest.load(manifest_path)
151
+ end
152
+ end
153
+
154
+ def setup
155
+ load_config
156
+ config.validate_ruby_executable
157
+ config.apply_autobuild_configuration
158
+ load_autoprojrc
159
+ load_main_initrb
160
+ config.each_reused_autoproj_installation do |p|
161
+ manifest.reuse(p)
162
+ end
163
+ load_manifest
164
+
165
+ Autobuild.prefix = prefix_dir
166
+ Autobuild.srcdir = root_dir
167
+ Autobuild.logdir = log_dir
168
+ env.prepare(root_dir)
169
+ Autoproj::OSDependencies::PACKAGE_HANDLERS.each do |pkg_mng|
170
+ pkg_mng.initialize_environment(env, manifest, root_dir)
171
+ end
172
+
173
+ Autoproj::OSDependencies.define_osdeps_mode_option(config)
174
+ osdeps.load_default
175
+ osdeps.osdeps_mode
176
+ end
177
+
178
+ def install_ruby_shims
179
+ install_suffix = ""
180
+ if match = /ruby(.*)$/.match(RbConfig::CONFIG['RUBY_INSTALL_NAME'])
181
+ install_suffix = match[1]
182
+ end
183
+
184
+ bindir = File.join(prefix_dir, 'bin')
185
+ FileUtils.mkdir_p bindir
186
+ env.add 'PATH', bindir
187
+
188
+ File.open(File.join(bindir, 'ruby'), 'w') do |io|
189
+ io.puts "#! /bin/sh"
190
+ io.puts "exec #{config.ruby_executable} \"$@\""
191
+ end
192
+ FileUtils.chmod 0755, File.join(bindir, 'ruby')
193
+
194
+ ['gem', 'irb', 'testrb'].each do |name|
195
+ # Look for the corresponding gem program
196
+ prg_name = "#{name}#{install_suffix}"
197
+ if File.file?(prg_path = File.join(RbConfig::CONFIG['bindir'], prg_name))
198
+ File.open(File.join(bindir, name), 'w') do |io|
199
+ io.puts "#! #{config.ruby_executable}"
200
+ io.puts "exec \"#{prg_path}\", *ARGV"
201
+ end
202
+ FileUtils.chmod 0755, File.join(bindir, name)
203
+ end
204
+ end
205
+ end
206
+
207
+ def update_autoproj(options = Hash.new)
208
+ options = validate_options options,
209
+ force: false, restart_on_update: true
210
+ return if !options[:force]
211
+
212
+ config.validate_ruby_executable
213
+
214
+ # This is a guard to avoid infinite recursion in case the user is
215
+ # running autoproj osdeps --force
216
+ if ENV['AUTOPROJ_RESTARTING'] == '1'
217
+ return
218
+ end
219
+
220
+ did_update =
221
+ begin
222
+ saved_flag = PackageManagers::GemManager.with_prerelease
223
+ PackageManagers::GemManager.with_prerelease = Autoproj.config.use_prerelease?
224
+ osdeps.install(%w{autobuild autoproj})
225
+ ensure
226
+ PackageManagers::GemManager.with_prerelease = saved_flag
227
+ end
228
+
229
+ # First things first, see if we need to update ourselves
230
+ if did_update && options[:restart_on_update]
231
+ puts
232
+ Autoproj.message 'autoproj and/or autobuild has been updated, restarting autoproj'
233
+ puts
234
+
235
+ # We updated autobuild or autoproj themselves ... Restart !
236
+ #
237
+ # ...But first save the configuration (!)
238
+ config.save
239
+ ENV['AUTOPROJ_RESTARTING'] = '1'
240
+ require 'rbconfig'
241
+ exec(ruby_executable, $0, *argv)
242
+ end
243
+ end
244
+
245
+ def set_as_main_workspace
246
+ Autoproj.workspace = self
247
+ Autoproj.root_dir = root_dir
248
+ Autobuild.env = env
249
+ end
250
+
251
+ # Loads autoproj/init.rb
252
+ #
253
+ # This is included in {setup}
254
+ def load_main_initrb
255
+ set_as_main_workspace
256
+
257
+ local_source = manifest.main_package_set
258
+ load_if_present(local_source, config_dir, "init.rb")
259
+ end
260
+
261
+ # Loads the .autoprojrc file
262
+ #
263
+ # This is included in {setup}
264
+ def load_autoprojrc
265
+ set_as_main_workspace
266
+
267
+ # Load the user-wide autoproj RC file
268
+ home_dir =
269
+ begin Dir.home
270
+ rescue ArgumentError
271
+ end
272
+
273
+ if home_dir
274
+ rcfile = File.join(home_dir, '.autoprojrc')
275
+ if File.file?(rcfile)
276
+ Kernel.load rcfile
277
+ end
278
+ end
279
+ end
280
+
281
+ # Load OS dependency information contained in our registered package
282
+ # sets into the provided osdep object
283
+ #
284
+ # This is included in {load_package_sets}
285
+ #
286
+ # @param [OSDependencies] osdeps the osdep handling object
287
+ # @return [void]
288
+ def load_osdeps_from_package_sets
289
+ manifest.each_osdeps_file do |pkg_set, file|
290
+ osdeps.merge(pkg_set.load_osdeps(file))
291
+ end
292
+ end
293
+
294
+ def load_package_sets(options = Hash.new)
295
+ options = validate_options options,
296
+ only_local: false,
297
+ checkout_only: true,
298
+ silent: false, # NOTE: this is ignored, enclose call with Autoproj.silent { }
299
+ reconfigure: false,
300
+ ignore_errors: false,
301
+ mainline: nil
302
+
303
+ Ops::Configuration.new(self).
304
+ load_package_sets(only_local: options[:only_local],
305
+ checkout_only: options[:checkout_only],
306
+ ignore_errors: options[:ignore_errors])
307
+
308
+ manifest.each_package_set do |pkg_set|
309
+ if Gem::Version.new(pkg_set.required_autoproj_version) > Gem::Version.new(Autoproj::VERSION)
310
+ raise ConfigError.new(pkg_set.source_file), "the #{pkg_set.name} package set requires autoproj v#{pkg_set.required_autoproj_version} but this is v#{Autoproj::VERSION}"
311
+ end
312
+ end
313
+
314
+ # Loads OS package definitions once and for all
315
+ load_osdeps_from_package_sets
316
+ # And exclude any package that is not available on this particular
317
+ # configuration
318
+ mark_unavailable_osdeps_as_excluded
319
+
320
+ # Load the required autobuild definitions
321
+ Autoproj.message("autoproj: loading ...", :bold)
322
+ if !options[:reconfigure]
323
+ Autoproj.message("run 'autoproj reconfigure' to change configuration options", :bold)
324
+ Autoproj.message("and use 'autoproj switch-config' to change the remote source for", :bold)
325
+ Autoproj.message("autoproj's main build configuration", :bold)
326
+ end
327
+ manifest.each_autobuild_file do |source, name|
328
+ import_autobuild_file source, name
329
+ end
330
+
331
+ # Now, load the package's importer configurations (from the various
332
+ # source.yml files)
333
+ mainline = options[:mainline]
334
+ if mainline.respond_to?(:to_str)
335
+ mainline = manifest.package_set(mainline)
336
+ end
337
+ manifest.load_importers(mainline: mainline)
338
+
339
+ # Auto-add packages that are
340
+ # * present on disk
341
+ # * listed in the layout part of the manifest
342
+ # * but have no definition
343
+ explicit = manifest.normalized_layout
344
+ explicit.each do |pkg_or_set, layout_level|
345
+ next if manifest.find_autobuild_package(pkg_or_set)
346
+ next if manifest.has_package_set?(pkg_or_set)
347
+
348
+ # This is not known. Check if we can auto-add it
349
+ full_path = File.expand_path(File.join(Autoproj.root_dir, layout_level, pkg_or_set))
350
+ next if !File.directory?(full_path)
351
+
352
+ handler, srcdir = Autoproj.package_handler_for(full_path)
353
+ if handler
354
+ Autoproj.message " auto-adding #{pkg_or_set} #{"in #{layout_level} " if layout_level != "/"}using the #{handler.gsub(/_package/, '')} package handler"
355
+ in_package_set(manifest.local_package_set, manifest.file) do
356
+ send(handler, pkg_or_set)
357
+ end
358
+ else
359
+ Autoproj.warn "cannot auto-add #{pkg_or_set}: unknown package type"
360
+ end
361
+ end
362
+
363
+ manifest.each_autobuild_package do |pkg|
364
+ Autobuild.each_utility do |uname, _|
365
+ pkg.utility(uname).enabled =
366
+ config.utility_enabled_for?(uname, pkg.name)
367
+ end
368
+ end
369
+
370
+ # We finished loading the configuration files. Not all configuration
371
+ # is done (since we need to process the package setup blocks), but
372
+ # save the current state of the configuration anyway.
373
+ config.save
374
+ end
375
+
376
+ def mark_unavailable_osdeps_as_excluded
377
+ osdeps.all_package_names.each do |osdep_name|
378
+ # If the osdep can be replaced by source packages, there's
379
+ # nothing to do really. The exclusions of the source packages
380
+ # will work as expected
381
+ if manifest.osdeps_overrides[osdep_name] || manifest.find_autobuild_package(osdep_name)
382
+ next
383
+ end
384
+
385
+ case availability = osdeps.availability_of(osdep_name)
386
+ when OSDependencies::UNKNOWN_OS
387
+ manifest.add_exclusion(osdep_name, "this operating system is unknown to autoproj")
388
+ when OSDependencies::WRONG_OS
389
+ manifest.add_exclusion(osdep_name, "there are definitions for it, but not for this operating system")
390
+ when OSDependencies::NONEXISTENT
391
+ manifest.add_exclusion(osdep_name, "it is marked as unavailable for this operating system")
392
+ end
393
+ end
394
+ end
395
+
396
+ def load_packages(selection = manifest.default_packages(false), options = Hash.new)
397
+ options = Hash[warn_about_ignored_packages: true, checkout_only: true].
398
+ merge(options)
399
+ ops = Ops::Import.new(self)
400
+ ops.import_packages(selection, options)
401
+ end
402
+
403
+ def setup_all_package_directories
404
+ # Override the package directories from our reused installations
405
+ imported_packages = Set.new
406
+ manifest.reused_installations.each do |imported_manifest|
407
+ imported_manifest.each do |imported_pkg|
408
+ imported_packages << imported_pkg.name
409
+ if pkg = manifest.find_package(imported_pkg.name)
410
+ pkg.autobuild.srcdir = imported_pkg.srcdir
411
+ pkg.autobuild.prefix = imported_pkg.prefix
412
+ end
413
+ end
414
+ end
415
+
416
+ manifest.packages.each_value do |pkg_def|
417
+ pkg = pkg_def.autobuild
418
+ next if imported_packages.include?(pkg_def.name)
419
+ setup_package_directories(pkg)
420
+ end
421
+ end
422
+
423
+ def setup_package_directories(pkg)
424
+ pkg_name = pkg.name
425
+
426
+ layout =
427
+ if config.randomize_layout?
428
+ Digest::SHA256.hexdigest(pkg_name)[0, 12]
429
+ else manifest.whereis(pkg_name)
430
+ end
431
+
432
+ srcdir =
433
+ if target = manifest.moved_packages[pkg_name]
434
+ File.join(layout, target)
435
+ else
436
+ File.join(layout, pkg_name)
437
+ end
438
+
439
+ prefixdir =
440
+ if config.separate_prefixes?
441
+ pkg_name
442
+ else
443
+ layout
444
+ end
445
+
446
+ pkg = manifest.find_autobuild_package(pkg_name)
447
+ pkg.srcdir = File.join(root_dir, srcdir)
448
+ if pkg.respond_to?(:builddir)
449
+ # If we're given an absolute build dir, we have to append the
450
+ # package name to it to make it unique
451
+ if Pathname.new(build_dir).absolute?
452
+ pkg.builddir = File.join(build_dir, pkg_name)
453
+ else
454
+ pkg.builddir = build_dir
455
+ end
456
+ end
457
+
458
+ pkg.prefix = File.join(prefix_dir, prefixdir)
459
+ pkg.doc_target_dir = File.join(prefix_dir, 'doc', pkg_name)
460
+ pkg.logdir = File.join(pkg.prefix, "log")
461
+ end
462
+
463
+ # Finalizes the configuration loading
464
+ #
465
+ # This must be done before before we run any dependency-sensitive
466
+ # operation (e.g. import)
467
+ def finalize_package_setup
468
+ set_as_main_workspace
469
+ # Now call the blocks that the user defined in the autobuild files. We do it
470
+ # now so that the various package directories are properly setup
471
+ manifest.packages.each_value do |pkg|
472
+ pkg.user_blocks.each do |blk|
473
+ blk[pkg.autobuild]
474
+ end
475
+ pkg.setup = true
476
+ end
477
+
478
+ manifest.each_package_set do |source|
479
+ load_if_present(source, source.local_dir, "overrides.rb")
480
+ end
481
+
482
+ Dir.glob(File.join( Autoproj.overrides_dir, "*.rb" ) ).sort.each do |file|
483
+ load file
484
+ end
485
+ end
486
+
487
+ # Finalizes the complete setup
488
+ #
489
+ # This must be done after all ignores/excludes and package selection
490
+ # have been properly set up (a.k.a. after package import)
491
+ def finalize_setup
492
+ # Finally, disable all ignored packages on the autobuild side
493
+ manifest.each_ignored_package do |pkg_name|
494
+ pkg = manifest.find_autobuild_package(pkg_name)
495
+ if !pkg
496
+ Autoproj.warn "ignore line #{pkg_name} does not match anything"
497
+ else
498
+ pkg.disable
499
+ end
500
+ end
501
+
502
+ setup_environment_from_packages
503
+
504
+ # We now have processed the process setup blocks. All configuration
505
+ # should be done and we can save the configuration data.
506
+ config.save
507
+ end
508
+
509
+ def setup_environment_from_packages
510
+ set_as_main_workspace
511
+ manifest.reused_installations.each do |reused_manifest|
512
+ reused_manifest.each do |pkg|
513
+ # The reused installations might have packages we do not
514
+ # know about, just ignore them
515
+ if pkg = manifest.find_autobuild_package(pkg)
516
+ pkg.update_environment
517
+ end
518
+ end
519
+ end
520
+
521
+ # Make sure that we have the environment of all selected packages
522
+ manifest.all_selected_packages(false).each do |pkg_name|
523
+ manifest.find_autobuild_package(pkg_name).update_environment
524
+ end
525
+ end
526
+
527
+ def export_installation_manifest
528
+ File.open(File.join(root_dir, ".autoproj-installation-manifest"), 'w') do |io|
529
+ manifest.all_selected_packages(false).each do |pkg_name|
530
+ if pkg = manifest.find_autobuild_package(pkg_name)
531
+ io.puts "#{pkg_name},#{pkg.srcdir},#{pkg.prefix}"
532
+ end
533
+ end
534
+ end
535
+ end
536
+ end
537
+
538
+ def self.workspace
539
+ @workspace ||= Workspace.new(root_dir)
540
+ end
541
+
542
+ def self.workspace=(ws)
543
+ @workspace = ws
544
+ end
545
+
546
+ def self.env
547
+ workspace.env
548
+ end
549
+ end
550
+