autoproj 1.13.7 → 2.0.0.b1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.gemtest +0 -0
  3. data/Manifest.txt +27 -21
  4. data/Rakefile +4 -6
  5. data/bin/alocate +5 -1
  6. data/bin/amake +3 -53
  7. data/bin/aup +3 -50
  8. data/bin/autoproj +3 -264
  9. data/bin/autoproj_bootstrap +294 -349
  10. data/bin/autoproj_bootstrap.in +27 -3
  11. data/lib/autoproj.rb +23 -1
  12. data/lib/autoproj/autobuild.rb +51 -89
  13. data/lib/autoproj/base.rb +0 -9
  14. data/lib/autoproj/build_option.rb +1 -3
  15. data/lib/autoproj/cli.rb +1 -0
  16. data/lib/autoproj/cli/base.rb +155 -0
  17. data/lib/autoproj/cli/bootstrap.rb +119 -0
  18. data/lib/autoproj/cli/build.rb +72 -0
  19. data/lib/autoproj/cli/cache.rb +31 -0
  20. data/lib/autoproj/cli/clean.rb +37 -0
  21. data/lib/autoproj/cli/commit.rb +41 -0
  22. data/lib/autoproj/cli/doc.rb +22 -0
  23. data/lib/autoproj/cli/envsh.rb +22 -0
  24. data/lib/autoproj/cli/inspection_tool.rb +73 -0
  25. data/lib/autoproj/cli/locate.rb +96 -0
  26. data/lib/autoproj/cli/log.rb +26 -0
  27. data/lib/autoproj/cli/main.rb +249 -0
  28. data/lib/autoproj/cli/main_test.rb +57 -0
  29. data/lib/autoproj/cli/osdeps.rb +30 -0
  30. data/lib/autoproj/cli/query.rb +43 -0
  31. data/lib/autoproj/cli/reconfigure.rb +19 -0
  32. data/lib/autoproj/cli/reset.rb +7 -32
  33. data/lib/autoproj/cli/show.rb +219 -0
  34. data/lib/autoproj/cli/snapshot.rb +1 -1
  35. data/lib/autoproj/cli/status.rb +149 -0
  36. data/lib/autoproj/cli/switch_config.rb +28 -0
  37. data/lib/autoproj/cli/tag.rb +9 -35
  38. data/lib/autoproj/cli/test.rb +34 -55
  39. data/lib/autoproj/cli/update.rb +158 -0
  40. data/lib/autoproj/cli/versions.rb +32 -69
  41. data/lib/autoproj/configuration.rb +95 -34
  42. data/lib/autoproj/default.osdeps +25 -35
  43. data/lib/autoproj/environment.rb +85 -63
  44. data/lib/autoproj/exceptions.rb +50 -0
  45. data/lib/autoproj/gitorious.rb +11 -9
  46. data/lib/autoproj/manifest.rb +199 -231
  47. data/lib/autoproj/metapackage.rb +0 -8
  48. data/lib/autoproj/ops/build.rb +1 -17
  49. data/lib/autoproj/ops/configuration.rb +92 -90
  50. data/lib/autoproj/ops/import.rb +222 -0
  51. data/lib/autoproj/ops/loader.rb +18 -8
  52. data/lib/autoproj/ops/main_config_switcher.rb +45 -73
  53. data/lib/autoproj/ops/snapshot.rb +5 -10
  54. data/lib/autoproj/ops/tools.rb +10 -44
  55. data/lib/autoproj/options.rb +35 -6
  56. data/lib/autoproj/osdeps.rb +97 -68
  57. data/lib/autoproj/package_selection.rb +39 -20
  58. data/lib/autoproj/package_set.rb +26 -24
  59. data/lib/autoproj/reporter.rb +91 -0
  60. data/lib/autoproj/system.rb +50 -149
  61. data/lib/autoproj/variable_expansion.rb +32 -6
  62. data/lib/autoproj/vcs_definition.rb +57 -17
  63. data/lib/autoproj/version.rb +1 -1
  64. data/lib/autoproj/workspace.rb +550 -0
  65. data/test/ops/test_snapshot.rb +26 -0
  66. data/test/test_package.rb +30 -0
  67. data/test/test_vcs_definition.rb +46 -0
  68. metadata +55 -50
  69. data/bin/autolocate +0 -3
  70. data/bin/autoproj-bootstrap +0 -68
  71. data/bin/autoproj-cache +0 -18
  72. data/bin/autoproj-clean +0 -13
  73. data/bin/autoproj-commit +0 -10
  74. data/bin/autoproj-create-set +0 -118
  75. data/bin/autoproj-doc +0 -28
  76. data/bin/autoproj-envsh +0 -14
  77. data/bin/autoproj-list +0 -69
  78. data/bin/autoproj-locate +0 -85
  79. data/bin/autoproj-log +0 -5
  80. data/bin/autoproj-query +0 -82
  81. data/bin/autoproj-reset +0 -13
  82. data/bin/autoproj-show +0 -192
  83. data/bin/autoproj-snapshot +0 -27
  84. data/bin/autoproj-switch-config +0 -24
  85. data/bin/autoproj-tag +0 -13
  86. data/bin/autoproj-test +0 -31
  87. data/bin/autoproj-versions +0 -20
  88. data/bin/autoproj_stress_test +0 -40
  89. data/lib/autoproj/cmdline.rb +0 -1649
@@ -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
+