autoproj 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
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