autoproj 1.12.6 → 1.13.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.
@@ -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