autoproj 1.1.0 → 1.1.1

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.
data/History.txt CHANGED
@@ -1,4 +1,14 @@
1
- = Version 1.1
1
+ = Version 1.1.1
2
+ * better general error reporting
3
+ * small fixes w.r.t. bootstrapping
4
+ * small improvements in the handling of layouts
5
+ * make it easier to write osdeps scripts: the OS names and version accept lists
6
+ as for instance:
7
+ debian,ubuntu:
8
+ lenny,9.04: package_to_install
9
+ * detect Ubuntu
10
+
11
+ = Version 1.1.0
2
12
  * added some sanity checks, especially w.r.t. an already existing GEM
3
13
  installation
4
14
  * improved the bootstrap
data/Rakefile CHANGED
@@ -28,8 +28,10 @@ begin
28
28
  desc "generate the bootstrap script"
29
29
  task 'bootstrap' do
30
30
  osdeps_code = File.read(File.join(Dir.pwd, 'lib', 'autoproj', 'osdeps.rb'))
31
+ osdeps_defaults = File.read(File.join(Dir.pwd, 'lib', 'autoproj', 'default.osdeps'))
31
32
  bootstrap_code = File.read(File.join(Dir.pwd, 'bin', 'autoproj_bootstrap.in')).
32
- gsub('OSDEPS_CODE', osdeps_code)
33
+ gsub('OSDEPS_CODE', osdeps_code).
34
+ gsub('OSDEPS_DEFAULTS', osdeps_defaults)
33
35
  File.open(File.join(Dir.pwd, 'doc', 'guide', 'src', 'autoproj_bootstrap'), 'w') do |io|
34
36
  io.write bootstrap_code
35
37
  end
data/bin/autoproj CHANGED
@@ -96,6 +96,7 @@ parser.parse!(args)
96
96
  mode = args.shift
97
97
  selected_packages = args.dup
98
98
  all_env_sh = Array.new
99
+ Autobuild::Reporting << Autoproj::Reporter.new
99
100
 
100
101
  def color(*args)
101
102
  Autoproj.console.color(*args)
@@ -212,8 +213,15 @@ def do_bootstrap(*args)
212
213
  name, value = args.shift.split("=")
213
214
  vcs_def[name] = value
214
215
  end
216
+
215
217
  vcs = Autoproj.normalize_vcs_definition(vcs_def)
216
- Autoproj::Manifest.import_whole_installation(vcs, File.join(Dir.pwd, "autoproj"))
218
+
219
+ # Install the OS dependencies required for this VCS
220
+ Autobuild::Reporting.report do
221
+ osdeps = Autoproj::OSDependencies.load_default
222
+ osdeps.install([vcs.type])
223
+ Autoproj::Manifest.import_whole_installation(vcs, File.join(Dir.pwd, "autoproj"))
224
+ end
217
225
 
218
226
  # Now write it in the config file
219
227
  File.open(File.join(Autoproj.config_dir, "config.yml"), "a") do |io|
@@ -274,7 +282,7 @@ begin
274
282
  # If we are under rubygems, check that the GEM_HOME is right ...
275
283
  if $LOADED_FEATURES.any? { |l| l =~ /rubygems/ }
276
284
  if ENV['GEM_HOME'] != Autoproj.gem_home
277
- raise ConfigError, "RubyGems is already loaded with a different GEM_HOME"
285
+ raise ConfigError, "RubyGems is already loaded with a different GEM_HOME, make sure you are loading the right env.sh script !"
278
286
  end
279
287
  end
280
288
  # Set the initial environment
@@ -282,9 +290,9 @@ begin
282
290
  # Set up some important autobuild parameters
283
291
  Autobuild.prefix = Autoproj.build_dir
284
292
  Autobuild.srcdir = root_dir
293
+ Autobuild.logdir = File.join(Autobuild.prefix, 'log')
285
294
  Autobuild.doc_errors = false
286
295
  Autobuild.do_doc = false
287
- Autobuild::Reporting << Autoproj::Reporter.new
288
296
  if mail_config[:to]
289
297
  Autobuild::Reporting << MailReporter.new(mail_config)
290
298
  end
@@ -310,8 +318,10 @@ begin
310
318
  # If we need to install some packages to import our remote sources, do it
311
319
  if !no_os_deps && !source_os_dependencies.empty?
312
320
  STDERR.puts color("autoproj: installing prepackaged dependencies to access the source definitions", :bold)
313
- osdeps = manifest.known_os_packages
314
- osdeps.install(source_os_dependencies)
321
+ Autobuild::Reporting.report do
322
+ osdeps = manifest.known_os_packages
323
+ osdeps.install(source_os_dependencies)
324
+ end
315
325
  end
316
326
 
317
327
  # Update the remote sources if there are any
@@ -414,14 +424,32 @@ begin
414
424
  if !no_os_deps
415
425
  STDERR.puts
416
426
  STDERR.puts color("autoproj: installing prepackaged dependencies for build system & version control", :bold)
417
- osdeps = manifest.known_os_packages
418
- osdeps.install(Autoproj.build_system_dependencies - source_os_dependencies)
427
+ Autobuild::Reporting.report do
428
+ osdeps = manifest.known_os_packages
429
+ osdeps.install(Autoproj.build_system_dependencies - source_os_dependencies)
430
+ end
419
431
  end
420
432
 
421
433
  # Now starts a different stage of the whole build. Until now, we were
422
434
  # working on the whole package set. Starting from now, we need to build the
423
435
  # package sets based on the layout file
436
+
437
+ # This keeps a hash of package_name => layout_name for all packages that
438
+ # have already been handled
439
+ handled_packages = Hash.new
440
+
424
441
  Autoproj.manifest.each_package_set(selected_packages) do |name, packages, enabled_packages|
442
+ packages -= handled_packages.keys.to_set
443
+ enabled_packages -= handled_packages.keys.to_set
444
+
445
+ # Here, 'packages' are the packages listed in the layout configuration,
446
+ # and 'enabled_packages' the ones that
447
+ #
448
+ # They do not (yet) take into account dependency information -- this is
449
+ # not doable as the manifests have not been loaded yet (the packages
450
+ # aren't imported). We add this information later on
451
+
452
+ # Setup directories
425
453
  srcdir = File.join(Autoproj.root_dir, name)
426
454
  prefix = File.join(Autoproj.build_dir, name)
427
455
  logdir = File.join(prefix, "log")
@@ -433,55 +461,78 @@ begin
433
461
  pkg.logdir = logdir
434
462
  end
435
463
 
436
- # We are doing a status, now is the right time
464
+ # We are doing a status, now is the right time. Otherwise, build ! But
465
+ # only if there is some packages to build (and avoid display of progress
466
+ # messages if there is nothing to build)
467
+ all_enabled_packages = Set.new
437
468
  STDERR.puts
438
469
  if only_do_status
439
- do_status(packages)
440
- next
441
- end
442
-
443
-
444
- # ... but build only the selected packages (and avoid display of
445
- # progress messages if there is nothing to build)
446
- if !enabled_packages.empty?
447
- STDERR.puts
448
- STDERR.puts color("autoproj: now building #{name}", :bold)
449
-
450
- STDERR.puts color(" updating packages", :bold)
470
+ do_status(enabled_packages)
471
+ elsif !enabled_packages.empty?
451
472
  Autobuild::Reporting.report do
452
- import_targets = enabled_packages.map { |pkg| "#{pkg}-import" }
453
- task "autoproj-#{name}-import" => import_targets
454
- Rake::Task["autoproj-#{name}-import"].invoke
455
- end
473
+ STDERR.puts
474
+ STDERR.puts color("autoproj: now building #{name}", :bold)
475
+
476
+ STDERR.puts color(" updating packages", :bold)
477
+ # We actually have a problem there: the packages in
478
+ # enabled_packages are *not* taking into account dependencies as
479
+ # we can't load the manifests yet ...
480
+ #
481
+ # So we have to make our own dependency analysis. Fortunately
482
+ # (for us), there is no need to import packages in order, so we
483
+ # can do a simple BFS
484
+ #
485
+ # Additional benefit: it computes the set of packages
486
+ packages_to_import = enabled_packages.dup
487
+ while !packages_to_import.empty?
488
+ import_now, packages_to_import = packages_to_import, Set.new
489
+ import_now.each do |pkg_name|
490
+ # Already handled at another place in the layout
491
+ next if handled_packages.has_key?(pkg_name)
492
+ # Already handled in this part of the layout
493
+ next if all_enabled_packages.include?(pkg_name)
494
+ # Not handled already. Import, load the manifest, add to
495
+ # all_enabled_packages and add the dependencies
496
+ Rake::Task["#{pkg_name}-import"].invoke
497
+ manifest.load_package_manifest(pkg_name)
498
+ all_enabled_packages << pkg_name
499
+ Autobuild::Package[pkg_name].dependencies.each do |dep_name|
500
+ if !handled_packages.has_key?(dep_name) &&
501
+ !packages.include?(dep_name)
502
+ raise ConfigError, "#{pkg_name}, at #{name} in the layout, depends on #{dep_name} but this package appears in the layout neither at #{name} nor before"
503
+ end
504
+ packages_to_import << dep_name
505
+ end
506
+ end
507
+ end
456
508
 
457
- # Load package manifests, apply dependencies to the autobuild definitions
458
- # and install OS packages
459
- manifest.load_package_manifests(packages)
460
- if !no_os_deps
461
- STDERR.puts color(" installing prepackaged dependencies", :bold)
462
- manifest.install_os_dependencies
463
- end
509
+ if !no_os_deps
510
+ STDERR.puts color(" installing prepackaged dependencies", :bold)
511
+ manifest.install_os_dependencies(all_enabled_packages)
512
+ end
464
513
 
465
- # Call the prepare target now, after we did the import *and* loaded
466
- # the manifests
467
- Autobuild::Reporting.report do
468
- prepare_targets = enabled_packages.map { |pkg| "#{pkg}-prepare" }
514
+ # Call the prepare target now, after we did the import *and* loaded
515
+ # the manifests
516
+ prepare_targets = all_enabled_packages.map { |pkg| "#{pkg}-prepare" }
469
517
  task "autoproj-#{name}-prepare" => prepare_targets
470
518
  Rake::Task["autoproj-#{name}-prepare"].invoke
471
- end
472
519
 
473
- # And now build
474
- if Autobuild.only_doc
475
- STDERR.puts color(" building and installing documentation", :bold)
476
- else
477
- STDERR.puts color(" building and installing packages", :bold)
478
- end
520
+ # And now build
521
+ if Autobuild.only_doc
522
+ STDERR.puts color(" building and installing documentation", :bold)
523
+ else
524
+ STDERR.puts color(" building and installing packages", :bold)
525
+ end
479
526
 
480
- Autobuild::Reporting.report do
481
527
  Autobuild.apply(enabled_packages, "autoproj-#{name}")
482
528
  Autobuild::Reporting.success
483
529
  end
484
530
  end
531
+
532
+ # Now mark them as handled
533
+ packages.each do |pkg_name|
534
+ handled_packages[pkg_name] = name
535
+ end
485
536
 
486
537
  # Now call the prepare target for all packages as it may be useful for
487
538
  # the rest of the builds and for the generation of the env.sh file
@@ -504,7 +555,8 @@ begin
504
555
  Autoproj.export_env_sh(name)
505
556
  end
506
557
 
507
- STDERR.puts <<EOTEXT
558
+ if mode == "build"
559
+ STDERR.puts <<-EOTEXT
508
560
 
509
561
 
510
562
  add the following lines at the bottom of your .bashrc:
@@ -514,7 +566,8 @@ WARNING: autoproj will not work until your restart all
514
566
  your consoles, or run the following in them:
515
567
  #{all_env_sh.map { |name| "$ source #{Dir.pwd}#{name}env.sh" }.join("\n ")}
516
568
 
517
- EOTEXT
569
+ EOTEXT
570
+ end
518
571
 
519
572
  rescue ConfigError => e
520
573
  STDERR.puts
@@ -4,7 +4,7 @@ ENV['GEM_HOME'] = "#{Dir.pwd}/.gems"
4
4
  ENV['PATH'] = "#{ENV['GEM_HOME']}/bin:#{ENV['PATH']}"
5
5
  if $LOADED_FEATURES.find { |str| str =~ /bygems/ }
6
6
  ENV['RUBYOPT'] = ""
7
- exec "ruby", __FILE__
7
+ exec "ruby", __FILE__, *ARGV
8
8
  end
9
9
 
10
10
  ENV['RUBYOPT'] = "-rubygems"
@@ -14,6 +14,7 @@ require 'set'
14
14
  require 'rubygems'
15
15
 
16
16
  module Autoproj
17
+ class ConfigError < RuntimeError; end
17
18
  class << self
18
19
  attr_reader :verbose
19
20
  end
@@ -35,7 +36,18 @@ require 'tempfile'
35
36
  module Autoproj
36
37
  class OSDependencies
37
38
  def self.load(file)
38
- OSDependencies.new(YAML.load(File.read(file)))
39
+ data =
40
+ begin
41
+ YAML.load(File.read(file))
42
+ rescue ArgumentError => e
43
+ raise ConfigError, "error in #{file}: #{e.message}"
44
+ end
45
+
46
+ OSDependencies.new(data)
47
+ end
48
+ AUTOPROJ_OSDEPS = File.join(File.expand_path(File.dirname(__FILE__)), 'default.osdeps')
49
+ def self.load_default
50
+ OSDependencies.load(AUTOPROJ_OSDEPS)
39
51
  end
40
52
 
41
53
  attr_reader :definitions
@@ -48,14 +60,38 @@ module Autoproj
48
60
  end
49
61
 
50
62
  def operating_system
51
- if File.exists?('/etc/debian_version')
52
- codename = File.read('/etc/debian_version').chomp
53
- ['debian', codename]
63
+ if @operating_system
64
+ return @operating_system
65
+ elsif data = os_from_lsb
66
+ @operating_system = data
54
67
  else
55
- raise ConfigError, "Unknown operating system"
68
+ # Need to do some heuristics unfortunately
69
+ @operating_system =
70
+ if File.exists?('/etc/debian_version')
71
+ codename = File.read('/etc/debian_version').chomp
72
+ ['debian', [codename]]
73
+ else
74
+ raise ConfigError, "Unknown operating system"
75
+ end
56
76
  end
77
+
78
+ # Normalize the names to lowercase
79
+ @operating_system =
80
+ [@operating_system[0].downcase,
81
+ @operating_system[1].map(&:downcase)]
82
+ end
83
+
84
+ def os_from_lsb
85
+ distributor = `lsb_release -i -s`
86
+ return unless $?.success?
87
+ distributor = distributor.chomp
88
+ codename = `lsb_release -c -s`.chomp
89
+ version = `lsb_release -r -s`.chomp
90
+
91
+ return [distributor, [codename, version]]
57
92
  end
58
93
 
94
+
59
95
  GAIN_ROOT_ACCESS = <<-EOSCRIPT
60
96
  if test `id -u` != "0"; then
61
97
  exec sudo /bin/bash $0 "$@"
@@ -64,27 +100,47 @@ module Autoproj
64
100
  EOSCRIPT
65
101
 
66
102
  OS_PACKAGE_INSTALL = {
67
- 'debian' => 'apt-get install -y %s'
103
+ 'debian' => 'apt-get install -y %s',
104
+ 'ubuntu' => 'apt-get install -y %s'
68
105
  }
69
106
 
70
107
  def generate_os_script(dependencies)
71
108
  os_name, os_version = operating_system
109
+ if !OS_PACKAGE_INSTALL.has_key?(os_name)
110
+ raise ConfigError, "I don't know how to install packages on #{os_name}"
111
+ end
112
+
72
113
  shell_snippets = ""
73
114
  os_packages = []
74
115
  dependencies.each do |name|
75
116
  dep_def = definitions[name]
76
117
  if !dep_def
77
118
  raise ConfigError, "I don't know how to install '#{name}'"
78
- elsif !dep_def[os_name]
119
+ end
120
+
121
+ # Find a matching entry for the OS name
122
+ os_entry = dep_def.find do |name_list, data|
123
+ name_list.split(',').
124
+ map(&:downcase).
125
+ any? { |n| n == os_name }
126
+ end
127
+
128
+ if !os_entry
79
129
  raise ConfigError, "I don't know how to install '#{name}' on #{os_name}"
80
130
  end
81
131
 
82
- data = dep_def[os_name]
132
+ data = os_entry.last
83
133
  if data.kind_of?(Hash)
84
- data = data[os_version]
85
- if !data
86
- raise ConfigError, "I don't know how to install '#{name}' on this specific version of #{os_name} (#{os_version})"
134
+ version_entry = data.find do |version_list, data|
135
+ version_list.to_s.split(',').
136
+ map(&:downcase).
137
+ any? { |v| os_version.include?(v) }
87
138
  end
139
+
140
+ if !version_entry
141
+ raise ConfigError, "I don't know how to install '#{name}' on this specific version of #{os_name} (#{os_version.join(", ")})"
142
+ end
143
+ data = version_entry.last
88
144
  end
89
145
 
90
146
  if data.respond_to?(:to_ary)
@@ -134,19 +190,21 @@ module Autoproj
134
190
  #
135
191
  # So, for now, reimplement rosdep by ourselves. Given how things
136
192
  # are done, this is actually not so hard.
137
- shell_script = generate_os_script(osdeps)
138
- if Autoproj.verbose
139
- STDERR.puts "Installing non-ruby OS dependencies with"
140
- STDERR.puts shell_script
141
- end
193
+ if !osdeps.empty?
194
+ shell_script = generate_os_script(osdeps)
195
+ if Autoproj.verbose
196
+ STDERR.puts "Installing non-ruby OS dependencies with"
197
+ STDERR.puts shell_script
198
+ end
142
199
 
143
- File.open('osdeps.sh', 'w') do |file|
144
- file.write shell_script
145
- end
146
- begin
147
- Autobuild::Subprocess.run 'autoproj', 'osdeps', 'bash', './osdeps.sh'
148
- ensure
149
- FileUtils.rm_f 'osdeps.sh'
200
+ File.open('osdeps.sh', 'w') do |file|
201
+ file.write shell_script
202
+ end
203
+ begin
204
+ Autobuild::Subprocess.run 'autoproj', 'osdeps', 'bash', './osdeps.sh'
205
+ ensure
206
+ FileUtils.rm_f 'osdeps.sh'
207
+ end
150
208
  end
151
209
 
152
210
  # Don't install gems that are already there ...
@@ -171,22 +229,45 @@ end
171
229
 
172
230
 
173
231
  DEFS = <<EODEFS
232
+ # The following definitions are needed to bootstrap autoproj
174
233
  ruby:
175
- debian:
176
- - ruby1.8-dev
177
- - ruby1.8
178
- - libopenssl-ruby1.8
234
+ debian,ubuntu:
235
+ 9.04,lenny:
236
+ - ruby1.8-dev
237
+ - ruby1.8
238
+ - libopenssl-ruby1.8
179
239
 
180
240
  build-essential:
181
- debian: build-essential
241
+ debian,ubuntu:
242
+ 9.04,lenny: build-essential
182
243
 
183
244
  libxml2:
184
- debian:
185
- - libxml2-dev
245
+ debian,ubuntu:
246
+ 9.04,lenny: libxml2-dev
186
247
  libxslt:
187
- debian:
188
- - libxslt1-dev
248
+ debian,ubuntu:
249
+ 9.04,lenny: libxslt1-dev
250
+
189
251
  autoproj: gem
252
+
253
+ # The following definitions are for the VCS and build systems
254
+ git:
255
+ debian,ubuntu:
256
+ 9.04,lenny: git-core
257
+
258
+ svn:
259
+ debian,ubuntu:
260
+ 9.04,lenny: svn
261
+
262
+ cmake:
263
+ debian,ubuntu:
264
+ 9.04,lenny: cmake
265
+
266
+ autotools:
267
+ debian,ubuntu:
268
+ 9.04,lenny: [automake1.9, autoconf]
269
+
270
+
190
271
  EODEFS
191
272
 
192
273
  PACKAGES = %w{ruby libxml2 libxslt build-essential}
@@ -197,12 +278,17 @@ if ARGV.first != "dev"
197
278
  packages += USER_PACKAGES
198
279
  end
199
280
 
200
- osdeps_management = Autoproj::OSDependencies.new(YAML.load(DEFS))
201
- STDERR.puts "autoproj: installing autoproj and its dependencies (this can take a long time)"
202
- osdeps_management.install(packages)
281
+ begin
282
+ osdeps_management = Autoproj::OSDependencies.new(YAML.load(DEFS))
283
+ STDERR.puts "autoproj: installing autoproj and its dependencies (this can take a long time)"
284
+ osdeps_management.install(packages)
285
+ rescue Autoproj::ConfigError => e
286
+ STDERR.puts "failed: #{e.message}"
287
+ exit(1)
288
+ end
203
289
 
204
290
  if ARGV.first != "dev"
205
- Autobuild::Subprocess.run('bootstrap', 'post', 'autoproj', 'bootstrap')
291
+ Autobuild::Subprocess.run('bootstrap', 'post', 'autoproj', 'bootstrap', *ARGV)
206
292
  end
207
293
 
208
294
  File.open('env.sh', 'w') do |io|
@@ -1,12 +1,38 @@
1
+ # The following definitions are needed to bootstrap autoproj
2
+ ruby:
3
+ debian,ubuntu:
4
+ 9.04,lenny:
5
+ - ruby1.8-dev
6
+ - ruby1.8
7
+ - libopenssl-ruby1.8
8
+
9
+ build-essential:
10
+ debian,ubuntu:
11
+ 9.04,lenny: build-essential
12
+
13
+ libxml2:
14
+ debian,ubuntu:
15
+ 9.04,lenny: libxml2-dev
16
+ libxslt:
17
+ debian,ubuntu:
18
+ 9.04,lenny: libxslt1-dev
19
+
20
+ autoproj: gem
21
+
22
+ # The following definitions are for the VCS and build systems
1
23
  git:
2
- debian: git-core
24
+ debian,ubuntu:
25
+ 9.04,lenny: git-core
3
26
 
4
27
  svn:
5
- debian: svn
28
+ debian,ubuntu:
29
+ 9.04,lenny: svn
6
30
 
7
31
  cmake:
8
- debian: cmake
32
+ debian,ubuntu:
33
+ 9.04,lenny: cmake
9
34
 
10
35
  autotools:
11
- debian: [automake1.9, autoconf]
36
+ debian,ubuntu:
37
+ 9.04,lenny: [automake1.9, autoconf]
12
38
 
@@ -52,7 +52,7 @@ module Autoproj
52
52
 
53
53
  # Set a new environment variable
54
54
  def self.env_set(name, *value)
55
- Autobuild.environment.delete(name)
55
+ Autobuild.environment[name] = nil
56
56
  env_add(name, *value)
57
57
  end
58
58
  def self.env_add(name, *value)
@@ -60,7 +60,7 @@ module Autoproj
60
60
  Autobuild.env_add(name, *value)
61
61
  end
62
62
  def self.env_set_path(name, *value)
63
- Autobuild.environment.delete(name)
63
+ Autobuild.environment[name] = nil
64
64
  env_add_path(name, *value)
65
65
  end
66
66
  def self.env_add_path(name, *value)
@@ -632,42 +632,50 @@ module Autoproj
632
632
  names.to_set
633
633
  end
634
634
 
635
- # Loads the package's manifest.xml files, and extracts dependency
636
- # information from them. The dependency information is then used applied
637
- # to the autobuild packages.
635
+ # Loads the package's manifest.xml file for the current package
638
636
  #
639
637
  # Right now, the absence of a manifest makes autoproj only issue a
640
638
  # warning. This will later be changed into an error.
641
- def load_package_manifests(selected_packages)
642
- packages.each_value do |package, source, file|
643
- next unless selected_packages.include?(package.name)
644
- manifest_path = File.join(package.srcdir, "manifest.xml")
645
- if !File.file?(manifest_path)
646
- Autoproj.warn "#{package.name} from #{source.name} does not have a manifest"
647
- next
648
- end
639
+ def load_package_manifest(pkg_name)
640
+ package, source, file = packages.values.
641
+ find { |package, source, file| package.name == pkg_name }
649
642
 
650
- manifest = PackageManifest.load(package, manifest_path)
651
- package_manifests[package.name] = manifest
643
+ if !pkg_name
644
+ raise ArgumentError, "package #{pkg_name} is not defined"
645
+ end
652
646
 
653
- manifest.each_package_dependency do |name|
654
- if Autoproj.verbose
655
- STDERR.puts " #{package.name} depends on #{name}"
656
- end
657
- begin
658
- package.depends_on name
659
- rescue Autobuild::ConfigException => e
660
- raise ConfigError, "manifest of #{package.name} from #{source.name} lists '#{name}' as dependency, but this package does not exist (manifest file: #{manifest_path})"
661
- end
647
+ manifest_path = File.join(package.srcdir, "manifest.xml")
648
+ if !File.file?(manifest_path)
649
+ Autoproj.warn "#{package.name} from #{source.name} does not have a manifest"
650
+ return
651
+ end
652
+
653
+ manifest = PackageManifest.load(package, manifest_path)
654
+ package_manifests[package.name] = manifest
655
+
656
+ manifest.each_package_dependency do |name|
657
+ if Autoproj.verbose
658
+ STDERR.puts " #{package.name} depends on #{name}"
659
+ end
660
+ begin
661
+ package.depends_on name
662
+ rescue Autobuild::ConfigException => e
663
+ raise ConfigError, "manifest of #{package.name} from #{source.name} lists '#{name}' as dependency, but this package does not exist (manifest file: #{manifest_path})"
662
664
  end
663
665
  end
664
666
  end
665
667
 
666
- AUTOPROJ_OSDEPS = File.join(File.expand_path(File.dirname(__FILE__)), 'default.osdeps')
668
+ # Loads the manifests for all packages known to this project.
669
+ #
670
+ # See #load_package_manifest
671
+ def load_package_manifests(selected_packages)
672
+ selected_packages.each(&:load_package_manifest)
673
+ end
674
+
667
675
  # Returns an OSDependencies instance that defined the known OS packages,
668
676
  # as well as how to install them
669
677
  def known_os_packages
670
- osdeps = OSDependencies.load(AUTOPROJ_OSDEPS)
678
+ osdeps = OSDependencies.load_default
671
679
 
672
680
  each_osdeps_file do |source, file|
673
681
  osdeps.merge(OSDependencies.load(file))
@@ -675,15 +683,17 @@ module Autoproj
675
683
  osdeps
676
684
  end
677
685
 
678
- def install_os_dependencies
686
+ def install_os_dependencies(packages)
679
687
  osdeps = known_os_packages
680
688
 
681
- all_packages = Set.new
682
- package_manifests.each_value do |pkg_manifest|
683
- all_packages |= pkg_manifest.each_os_dependency.to_set
689
+ required_os_packages = Set.new
690
+ packages.each do |pkg_name|
691
+ if manifest = package_manifests[pkg_name]
692
+ required_os_packages |= manifest.each_os_dependency.to_set
693
+ end
684
694
  end
685
695
 
686
- osdeps.install(all_packages)
696
+ osdeps.install(required_os_packages)
687
697
  end
688
698
  end
689
699
 
@@ -2,7 +2,18 @@ require 'tempfile'
2
2
  module Autoproj
3
3
  class OSDependencies
4
4
  def self.load(file)
5
- OSDependencies.new(YAML.load(File.read(file)))
5
+ data =
6
+ begin
7
+ YAML.load(File.read(file))
8
+ rescue ArgumentError => e
9
+ raise ConfigError, "error in #{file}: #{e.message}"
10
+ end
11
+
12
+ OSDependencies.new(data)
13
+ end
14
+ AUTOPROJ_OSDEPS = File.join(File.expand_path(File.dirname(__FILE__)), 'default.osdeps')
15
+ def self.load_default
16
+ OSDependencies.load(AUTOPROJ_OSDEPS)
6
17
  end
7
18
 
8
19
  attr_reader :definitions
@@ -15,14 +26,38 @@ module Autoproj
15
26
  end
16
27
 
17
28
  def operating_system
18
- if File.exists?('/etc/debian_version')
19
- codename = File.read('/etc/debian_version').chomp
20
- ['debian', codename]
29
+ if @operating_system
30
+ return @operating_system
31
+ elsif data = os_from_lsb
32
+ @operating_system = data
21
33
  else
22
- raise ConfigError, "Unknown operating system"
34
+ # Need to do some heuristics unfortunately
35
+ @operating_system =
36
+ if File.exists?('/etc/debian_version')
37
+ codename = File.read('/etc/debian_version').chomp
38
+ ['debian', [codename]]
39
+ else
40
+ raise ConfigError, "Unknown operating system"
41
+ end
23
42
  end
43
+
44
+ # Normalize the names to lowercase
45
+ @operating_system =
46
+ [@operating_system[0].downcase,
47
+ @operating_system[1].map(&:downcase)]
24
48
  end
25
49
 
50
+ def os_from_lsb
51
+ distributor = `lsb_release -i -s`
52
+ return unless $?.success?
53
+ distributor = distributor.chomp
54
+ codename = `lsb_release -c -s`.chomp
55
+ version = `lsb_release -r -s`.chomp
56
+
57
+ return [distributor, [codename, version]]
58
+ end
59
+
60
+
26
61
  GAIN_ROOT_ACCESS = <<-EOSCRIPT
27
62
  if test `id -u` != "0"; then
28
63
  exec sudo /bin/bash $0 "$@"
@@ -31,27 +66,47 @@ module Autoproj
31
66
  EOSCRIPT
32
67
 
33
68
  OS_PACKAGE_INSTALL = {
34
- 'debian' => 'apt-get install -y %s'
69
+ 'debian' => 'apt-get install -y %s',
70
+ 'ubuntu' => 'apt-get install -y %s'
35
71
  }
36
72
 
37
73
  def generate_os_script(dependencies)
38
74
  os_name, os_version = operating_system
75
+ if !OS_PACKAGE_INSTALL.has_key?(os_name)
76
+ raise ConfigError, "I don't know how to install packages on #{os_name}"
77
+ end
78
+
39
79
  shell_snippets = ""
40
80
  os_packages = []
41
81
  dependencies.each do |name|
42
82
  dep_def = definitions[name]
43
83
  if !dep_def
44
84
  raise ConfigError, "I don't know how to install '#{name}'"
45
- elsif !dep_def[os_name]
85
+ end
86
+
87
+ # Find a matching entry for the OS name
88
+ os_entry = dep_def.find do |name_list, data|
89
+ name_list.split(',').
90
+ map(&:downcase).
91
+ any? { |n| n == os_name }
92
+ end
93
+
94
+ if !os_entry
46
95
  raise ConfigError, "I don't know how to install '#{name}' on #{os_name}"
47
96
  end
48
97
 
49
- data = dep_def[os_name]
98
+ data = os_entry.last
50
99
  if data.kind_of?(Hash)
51
- data = data[os_version]
52
- if !data
53
- raise ConfigError, "I don't know how to install '#{name}' on this specific version of #{os_name} (#{os_version})"
100
+ version_entry = data.find do |version_list, data|
101
+ version_list.to_s.split(',').
102
+ map(&:downcase).
103
+ any? { |v| os_version.include?(v) }
104
+ end
105
+
106
+ if !version_entry
107
+ raise ConfigError, "I don't know how to install '#{name}' on this specific version of #{os_name} (#{os_version.join(", ")})"
54
108
  end
109
+ data = version_entry.last
55
110
  end
56
111
 
57
112
  if data.respond_to?(:to_ary)
@@ -101,19 +156,21 @@ module Autoproj
101
156
  #
102
157
  # So, for now, reimplement rosdep by ourselves. Given how things
103
158
  # are done, this is actually not so hard.
104
- shell_script = generate_os_script(osdeps)
105
- if Autoproj.verbose
106
- STDERR.puts "Installing non-ruby OS dependencies with"
107
- STDERR.puts shell_script
108
- end
159
+ if !osdeps.empty?
160
+ shell_script = generate_os_script(osdeps)
161
+ if Autoproj.verbose
162
+ STDERR.puts "Installing non-ruby OS dependencies with"
163
+ STDERR.puts shell_script
164
+ end
109
165
 
110
- File.open('osdeps.sh', 'w') do |file|
111
- file.write shell_script
112
- end
113
- begin
114
- Autobuild::Subprocess.run 'autoproj', 'osdeps', 'bash', './osdeps.sh'
115
- ensure
116
- FileUtils.rm_f 'osdeps.sh'
166
+ File.open('osdeps.sh', 'w') do |file|
167
+ file.write shell_script
168
+ end
169
+ begin
170
+ Autobuild::Subprocess.run 'autoproj', 'osdeps', 'bash', './osdeps.sh'
171
+ ensure
172
+ FileUtils.rm_f 'osdeps.sh'
173
+ end
117
174
  end
118
175
 
119
176
  # Don't install gems that are already there ...
@@ -1,3 +1,3 @@
1
1
  module Autoproj
2
- VERSION = "1.1.0"
2
+ VERSION = "1.1.1"
3
3
  end
data/samples/manifest CHANGED
@@ -1,9 +1,18 @@
1
1
  package_sets:
2
- # Example source from a git repository
2
+ # Example from the RubyInMotion orocos package set
3
3
  # - type: git
4
- # url: git://github.com/doudou/autoproj.orocos.git
5
- #
6
- # If you want to enable only a subset of the listed sources,
7
- # list their names in the following section. Note that the
8
- # name is given in the source's source.yml file
4
+ # url: git://github.com/doudou/rubim.orocos.git
9
5
 
6
+ # If you want to adapt the layout to your needs, uncomment the following (again,
7
+ # RubyInMotion orocos package set)
8
+ # layout:
9
+ # - orocos:
10
+ # - rubim.orocos
11
+ #
12
+ # The principle is to have a hierarchy of names, package names and names of
13
+ # package sets. In the above example, all packages of the rubim.orocos package
14
+ # set will be built under the orocos/ subdirectory. Alternatively, you could do:
15
+ #
16
+ # layout:
17
+ # - tools:
18
+ # - rubim.orocos
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: autoproj
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvain Joyeux
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-15 00:00:00 +02:00
12
+ date: 2009-10-16 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency