autoproj 1.12.6 → 1.13.0.b1

Sign up to get free protection for your applications and to get access to all the features.
@@ -24,8 +24,8 @@ module Autoproj
24
24
  @@packages.delete(text_name)
25
25
  end
26
26
 
27
- def import(only_local = false)
28
- importer.import(self, only_local)
27
+ def import(options = Hash.new)
28
+ importer.import(self, options)
29
29
  end
30
30
 
31
31
  def add_stat(*args)
@@ -49,7 +49,12 @@ module Autoproj
49
49
 
50
50
  def load_autoprojrc
51
51
  # Load the user-wide autoproj RC file
52
- if home_dir = Dir.home
52
+ home_dir =
53
+ begin Dir.home
54
+ rescue ArgumentError
55
+ end
56
+
57
+ if home_dir
53
58
  rcfile = File.join(home_dir, '.autoprojrc')
54
59
  if File.file?(rcfile)
55
60
  Kernel.load rcfile
@@ -87,6 +92,34 @@ module Autoproj
87
92
  end
88
93
  end
89
94
 
95
+ def resolve_selection(user_selection, options = Hash.new)
96
+ options = Kernel.validate_options options,
97
+ recursive: true,
98
+ ignore_non_imported_packages: false
99
+
100
+ resolved_selection = CmdLine.
101
+ resolve_user_selection(user_selection, filter: false)
102
+ if options[:ignore_non_imported_packages]
103
+ manifest.each_autobuild_package do |pkg|
104
+ if !File.directory?(pkg.srcdir)
105
+ manifest.ignore_package(pkg.name)
106
+ end
107
+ end
108
+ end
109
+ resolved_selection.filter_excluded_and_ignored_packages(manifest)
110
+
111
+ packages =
112
+ if options[:recursive]
113
+ CmdLine.import_packages(
114
+ resolved_selection,
115
+ warn_about_ignored_packages: false)
116
+ else
117
+ resolved_selection.to_a
118
+ end
119
+
120
+ packages
121
+ end
122
+
90
123
  extend Tools
91
124
  end
92
125
  end
@@ -369,6 +369,17 @@ fi
369
369
  "zypper -n install '%s'")
370
370
  end
371
371
 
372
+ def filter_uptodate_packages(packages)
373
+ result = `LANG=C rpm -q --whatprovides '#{packages.join("' '")}'`
374
+ has_all_pkgs = $?.success?
375
+
376
+ if !has_all_pkgs
377
+ return packages # let zypper filter, we need root now anyways
378
+ else
379
+ return []
380
+ end
381
+ end
382
+
372
383
  def install(packages)
373
384
  patterns, packages = packages.partition { |pkg| pkg =~ /^@/ }
374
385
  patterns = patterns.map { |str| str[1..-1] }
@@ -401,21 +412,21 @@ fi
401
412
  result = `LANG=C rpm -q --queryformat "%{NAME}\n" '#{packages.join("' '")}'`
402
413
 
403
414
  installed_packages = []
404
- new_packages = []
415
+ new_packages = []
405
416
  result.split("\n").each_with_index do |line, index|
406
- line = line.strip
417
+ line = line.strip
407
418
  if line =~ /package (.*) is not installed/
408
- package_name = $1
409
- if !packages.include?(package_name) # something is wrong, fallback to installing everything
410
- return packages
411
- end
419
+ package_name = $1
420
+ if !packages.include?(package_name) # something is wrong, fallback to installing everything
421
+ return packages
422
+ end
412
423
  new_packages << package_name
413
- else
414
- package_name = line.strip
415
- if !packages.include?(package_name) # something is wrong, fallback to installing everything
416
- return packages
417
- end
418
- installed_packages << package_name
424
+ else
425
+ package_name = line.strip
426
+ if !packages.include?(package_name) # something is wrong, fallback to installing everything
427
+ return packages
428
+ end
429
+ installed_packages << package_name
419
430
  end
420
431
  end
421
432
  new_packages
@@ -533,13 +544,13 @@ fi
533
544
  Autoproj.manifest.each_reused_autoproj_installation do |p|
534
545
  p_gems = File.join(p, '.gems')
535
546
  if File.directory?(p_gems)
536
- Autobuild.env_add_path 'GEM_PATH', p_gems
537
- Autobuild.env_add_path 'PATH', File.join(p_gems, 'bin')
547
+ Autobuild.env_push_path 'GEM_PATH', p_gems
548
+ Autobuild.env_push_path 'PATH', File.join(p_gems, 'bin')
538
549
  end
539
550
  end
540
- Autobuild.env_add_path 'GEM_PATH', gem_home
551
+ Autobuild.env_push_path 'GEM_PATH', gem_home
541
552
  Autobuild.env_set 'GEM_HOME', gem_home
542
- Autobuild.env_add_path 'PATH', "#{gem_home}/bin"
553
+ Autobuild.env_push_path 'PATH', "#{gem_home}/bin"
543
554
 
544
555
  # Now, reset the directories in our own RubyGems instance
545
556
  Gem.paths = ENV
@@ -549,6 +560,7 @@ fi
549
560
  if cache = cache_dir
550
561
  gem_cache_dir = File.join(gem_home, 'cache')
551
562
  if !File.symlink?(gem_cache_dir) || File.readlink(gem_cache_dir) != cache
563
+ FileUtils.mkdir_p gem_home
552
564
  FileUtils.rm_rf gem_cache_dir
553
565
  Autoproj.create_symlink(cache, gem_cache_dir)
554
566
  end
@@ -32,6 +32,19 @@ module Autoproj
32
32
  @autobuild, @package_set, @file =
33
33
  autobuild, package_set, file
34
34
  @user_blocks = []
35
+ @modes = ['import', 'build']
36
+ end
37
+
38
+ # The modes in which this package will be used
39
+ #
40
+ # Mainly used during dependency resolution to disable unneeded
41
+ # dependencies
42
+ #
43
+ # @return [Array<String>]
44
+ def modes
45
+ @modes + autobuild.utilities.values.
46
+ find_all { |u| u.enabled? }.
47
+ map(&:name)
35
48
  end
36
49
 
37
50
  # The package name
@@ -70,46 +70,49 @@ module Autoproj
70
70
  @xml = doc
71
71
  end
72
72
 
73
- def each_dependency(&block)
74
- if block_given?
75
- each_os_dependency(&block)
76
- each_package_dependency(&block)
77
- else
78
- enum_for(:each_dependency, &block)
73
+ def each_dependency(in_modes = Array.new, &block)
74
+ return enum_for(__method__) if !block_given?
75
+
76
+ depend_nodes = xml.elements.to_a('package/depend') +
77
+ xml.elements.to_a('package/depend_optional') +
78
+ xml.elements.to_a('package/rosdep')
79
+ in_modes.each do |m|
80
+ depend_nodes += xml.elements.to_a("package/#{m}_depend")
79
81
  end
80
- end
81
82
 
82
- def each_os_dependency
83
- if block_given?
84
- xml.elements.each('package/rosdep') do |node|
85
- yield(node.attributes['name'], false)
83
+ depend_nodes.each do |node|
84
+ dependency = node.attributes['package'] || node.attributes['name']
85
+ optional = (node.attributes['optional'].to_s == '1' || node.name == "depend_optional")
86
+ modes = node.attributes['modes'].to_s.split(',')
87
+ if node.name =~ /^(\w+)_depend$/
88
+ modes << $1
89
+ end
90
+ if !modes.empty? && modes.none? { |m| in_modes.include?(m) }
91
+ next
86
92
  end
87
- package.os_packages.each do |name|
88
- yield(name, false)
93
+
94
+ if dependency
95
+ yield(dependency, optional)
96
+ elsif node.name == 'rosdep'
97
+ raise ConfigError.new, "manifest of #{package.name} has a <rosdep> tag without a 'name' attribute"
98
+ else
99
+ raise ConfigError.new, "manifest of #{package.name} has a <#{node.name}> tag without a 'package' attribute"
89
100
  end
90
- else
91
- enum_for :each_os_dependency
92
101
  end
93
- end
94
102
 
95
- def each_package_dependency
96
- if block_given?
97
- depend_nodes = xml.elements.to_a('package/depend') +
98
- xml.elements.to_a('package/depend_optional')
103
+ package.os_packages.each do |name|
104
+ yield(name, false)
105
+ end
106
+ end
99
107
 
100
- depend_nodes.each do |node|
101
- dependency = node.attributes['package']
102
- optional = (node.attributes['optional'].to_s == '1' || node.name == "depend_optional")
108
+ def each_os_dependency(modes = Array.new, &block)
109
+ Autoproj.warn "PackageManifest#each_os_dependency called, fix your code"
110
+ return each_dependency(modes, &block)
111
+ end
103
112
 
104
- if dependency
105
- yield(dependency, optional)
106
- else
107
- raise ConfigError.new, "manifest of #{package.name} has a <depend> tag without a 'package' attribute"
108
- end
109
- end
110
- else
111
- enum_for :each_package_dependency
112
- end
113
+ def each_package_dependency(modes = Array.new)
114
+ Autoproj.warn "PackageManifest#each_os_dependency called, fix your code"
115
+ return each_dependency(modes, &block)
113
116
  end
114
117
 
115
118
  def each_maintainer
@@ -56,6 +56,9 @@ module Autoproj
56
56
  attr_reader :source_definition
57
57
  attr_reader :constants_definitions
58
58
 
59
+ # The set of overrides defined in this package set
60
+ attr_reader :overrides
61
+
59
62
  # Sets the auto_imports flag
60
63
  #
61
64
  # @see auto_imports?
@@ -89,6 +92,7 @@ module Autoproj
89
92
  @vcs = vcs
90
93
  @osdeps = OSDependencies.new
91
94
  @all_osdeps = []
95
+ @overrides = Array.new
92
96
 
93
97
  @provides = Set.new
94
98
  @imports = Set.new
@@ -114,11 +118,14 @@ module Autoproj
114
118
  # True if this source has already been checked out on the local autoproj
115
119
  # installation
116
120
  def present?; File.directory?(raw_local_dir) end
121
+ # True if this is the main package set (i.e. the main autoproj
122
+ # configuration)
123
+ def main?; false end
117
124
  # True if this source is local, i.e. is not under a version control
118
125
  def local?; vcs.local? end
119
126
  # True if this source defines nothing
120
127
  def empty?
121
- !source_definition['version_control'] && !source_definition['overrides']
128
+ !source_definition['version_control'] && overrides.empty?
122
129
  !each_package.find { true } &&
123
130
  !File.exists?(File.join(raw_local_dir, "overrides.rb")) &&
124
131
  !File.exists?(File.join(raw_local_dir, "init.rb"))
@@ -133,7 +140,9 @@ module Autoproj
133
140
  Hash.new
134
141
  else
135
142
  package = create_autobuild_package
136
- package.importer.snapshot(package, target_dir)
143
+ if package.importer.respond_to?(:snapshot)
144
+ package.importer.snapshot(package, target_dir)
145
+ end
137
146
  end
138
147
  end
139
148
 
@@ -326,6 +335,15 @@ module Autoproj
326
335
  end
327
336
 
328
337
  parse_source_definition
338
+ @overrides = load_overrides
339
+ end
340
+
341
+ def load_overrides
342
+ if data = source_definition['overrides']
343
+ [[source_file, data]]
344
+ else
345
+ []
346
+ end
329
347
  end
330
348
 
331
349
  def parse_source_definition
@@ -377,6 +395,10 @@ module Autoproj
377
395
  #
378
396
  # The returned value is a VCSDefinition object.
379
397
  def version_control_field(package_name, section_name, validate = true)
398
+ vcs_field( source_definition, package_name, section_name, validate )
399
+ end
400
+
401
+ def vcs_field( source_definition, package_name, section_name, validate )
380
402
  urls = source_definition['urls'] || Hash.new
381
403
  urls['HOME'] = ENV['HOME']
382
404
 
@@ -395,6 +417,10 @@ module Autoproj
395
417
  if all_vcs
396
418
  all_vcs.each do |spec|
397
419
  spec = spec.dup
420
+ if !spec.kind_of?(Hash)
421
+ raise ConfigError.new, "wrong format for the #{spec} entry, expected #{spec} followed by a colon and one importer option per following line"
422
+ end
423
+
398
424
  if spec.values.size != 1
399
425
  # Maybe the user wrote the spec like
400
426
  # - package_name:
@@ -495,16 +521,23 @@ module Autoproj
495
521
  # @param [VCSDefinition] the vcs to be updated
496
522
  # @return [VCSDefinition] the new, updated vcs object
497
523
  def overrides_for(package_name, vcs)
498
- new_spec, new_raw_entry = version_control_field(package_name, 'overrides', false)
499
- return vcs if !new_spec
524
+ overrides.each do |file, override|
525
+ new_spec, new_raw_entry =
526
+ Autoproj.in_file file do
527
+ vcs_field(Hash['overrides' => override], package_name, 'overrides', false)
528
+ end
500
529
 
501
- Autoproj.in_file source_file do
502
- begin
503
- vcs.update(new_spec, new_raw_entry)
504
- rescue ConfigError => e
505
- raise ConfigError.new, "invalid resulting VCS specification in the overrides section for package #{package_name}: #{e.message}"
530
+ if new_spec
531
+ Autoproj.in_file file do
532
+ begin
533
+ vcs = vcs.update(new_spec, new_raw_entry)
534
+ rescue ConfigError => e
535
+ raise ConfigError.new, "invalid resulting VCS specification in the overrides section for package #{package_name}: #{e.message}"
536
+ end
537
+ end
506
538
  end
507
539
  end
540
+ vcs
508
541
  end
509
542
 
510
543
  # Enumerates the Autobuild::Package instances that are defined in this
@@ -547,6 +580,10 @@ module Autoproj
547
580
  'main configuration'
548
581
  end
549
582
 
583
+ def main?
584
+ true
585
+ end
586
+
550
587
  def local?
551
588
  true
552
589
  end
@@ -563,12 +600,12 @@ module Autoproj
563
600
  File.join(Autoproj.config_dir, "manifest")
564
601
  end
565
602
 
566
- def overrides_yml_path
603
+ def overrides_file_path
567
604
  File.join(Autoproj.config_dir, "overrides.yml")
568
605
  end
569
606
 
570
607
  def source_file
571
- overrides_yml_path
608
+ manifest_path
572
609
  end
573
610
 
574
611
  # Returns the default importer for this package set
@@ -580,21 +617,41 @@ module Autoproj
580
617
  def load_description_file
581
618
  @source_definition = raw_description_file
582
619
  parse_source_definition
620
+ @overrides = load_overrides
621
+ end
622
+
623
+ def load_overrides
624
+ files = Dir.glob(File.join( Autoproj.overrides_dir, "*.yml" ) ).sort
625
+ overrides = files.map do |file|
626
+ source_data = Autoproj.in_file(file, Autoproj::YAML_LOAD_ERROR) do
627
+ YAML.load(File.read(file)) || Array.new
628
+ end
629
+ source_data =
630
+ if source_data.respond_to?(:to_ary)
631
+ source_data
632
+ else source_data['overrides'] || Array.new
633
+ end
634
+ [file, source_data]
635
+ end
636
+ overrides + super
583
637
  end
584
638
 
585
639
  def raw_description_file
586
- if File.file?(overrides_yml_path)
587
- description = Autoproj.in_file(overrides_yml_path, Autoproj::YAML_LOAD_ERROR) do
588
- YAML.load(File.read(overrides_yml_path)) || Hash.new
640
+ description = Hash[
641
+ 'imports' => Array.new,
642
+ 'version_control' => Array.new,
643
+ 'overrides' => Array.new]
644
+ if File.file?(overrides_file_path)
645
+ overrides_data = Autoproj.in_file(overrides_file_path, Autoproj::YAML_LOAD_ERROR) do
646
+ YAML.load(File.read(overrides_file_path)) || Hash.new
589
647
  end
590
- else
591
- description = Hash.new
648
+ description = description.merge(overrides_data)
592
649
  end
593
650
 
594
651
  manifest_data = Autoproj.in_file(manifest_path, Autoproj::YAML_LOAD_ERROR) do
595
652
  YAML.load(File.read(manifest_path)) || Hash.new
596
653
  end
597
- description['imports'] = (description['imports'] || Array.new).
654
+ description['imports'] = description['imports'].
598
655
  concat(manifest_data['package_sets'] || Array.new)
599
656
  description['name'] = name
600
657
  description
@@ -36,23 +36,26 @@ module Autoproj
36
36
  return @root_dir
37
37
  end
38
38
 
39
- root_dir_rx =
40
- if Autobuild.windows? then /^[a-zA-Z]:\\\\$/
41
- else /^\/$/
39
+ path = Pathname.pwd
40
+ while !path.root?
41
+ if (path + "autoproj" + 'manifest').file?
42
+ break
42
43
  end
43
-
44
- while root_dir_rx !~ dir && !File.directory?(File.join(dir, "autoproj"))
45
- dir = File.dirname(dir)
44
+ path = path.parent
46
45
  end
47
- if root_dir_rx =~ dir
46
+
47
+ if path.root?
48
48
  raise UserError, "not in a Autoproj installation"
49
49
  end
50
50
 
51
- #Preventing backslashed in path, that might be confusing on some path compares
51
+ result = path.to_s
52
+ # I don't know if this is still useful or not ... but it does not hurt
53
+ #
54
+ # Preventing backslashed in path, that might be confusing on some path compares
52
55
  if Autobuild.windows?
53
- dir = dir.gsub(/\\/,'/')
56
+ result = result.gsub(/\\/,'/')
54
57
  end
55
- dir
58
+ result
56
59
  end
57
60
 
58
61
  # Returns the configuration directory for this autoproj installation.
@@ -63,6 +66,16 @@ module Autoproj
63
66
  File.join(root_dir, "autoproj")
64
67
  end
65
68
 
69
+ OVERRIDES_DIR = "overrides.d"
70
+
71
+ # Returns the directory containing overrides files
72
+ #
73
+ # If the current directory is not in an autoproj installation,
74
+ # raises UserError.
75
+ def self.overrides_dir
76
+ File.join(config_dir, OVERRIDES_DIR)
77
+ end
78
+
66
79
  # @deprecated use Autobuild.find_in_path instead
67
80
  #
68
81
  # Warning: the autobuild method returns nil (instead of raising) if the