autoproj 2.0.0.rc37 → 2.0.0.rc38

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -2
  3. data/Rakefile +1 -1
  4. data/bin/autoproj_bootstrap +34 -2
  5. data/bin/autoproj_bootstrap.in +4 -2
  6. data/bin/autoproj_install +34 -2
  7. data/bin/autoproj_install.in +4 -2
  8. data/lib/autoproj.rb +9 -2
  9. data/lib/autoproj/autobuild.rb +13 -742
  10. data/lib/autoproj/autobuild_extensions/archive_importer.rb +44 -0
  11. data/lib/autoproj/autobuild_extensions/dsl.rb +439 -0
  12. data/lib/autoproj/autobuild_extensions/git.rb +116 -0
  13. data/lib/autoproj/autobuild_extensions/package.rb +159 -0
  14. data/lib/autoproj/autobuild_extensions/svn.rb +11 -0
  15. data/lib/autoproj/cli/base.rb +17 -18
  16. data/lib/autoproj/cli/clean.rb +1 -2
  17. data/lib/autoproj/cli/envsh.rb +1 -2
  18. data/lib/autoproj/cli/inspection_tool.rb +12 -21
  19. data/lib/autoproj/cli/locate.rb +130 -73
  20. data/lib/autoproj/cli/main.rb +31 -5
  21. data/lib/autoproj/cli/main_plugin.rb +79 -0
  22. data/lib/autoproj/cli/main_test.rb +19 -5
  23. data/lib/autoproj/cli/osdeps.rb +1 -2
  24. data/lib/autoproj/cli/patcher.rb +21 -0
  25. data/lib/autoproj/cli/query.rb +34 -41
  26. data/lib/autoproj/cli/show.rb +121 -52
  27. data/lib/autoproj/cli/status.rb +4 -5
  28. data/lib/autoproj/cli/tag.rb +1 -1
  29. data/lib/autoproj/cli/test.rb +7 -6
  30. data/lib/autoproj/cli/update.rb +8 -22
  31. data/lib/autoproj/cli/versions.rb +1 -2
  32. data/lib/autoproj/configuration.rb +1 -1
  33. data/lib/autoproj/environment.rb +2 -7
  34. data/lib/autoproj/exceptions.rb +10 -8
  35. data/lib/autoproj/find_workspace.rb +46 -12
  36. data/lib/autoproj/installation_manifest.rb +34 -25
  37. data/lib/autoproj/local_package_set.rb +86 -0
  38. data/lib/autoproj/manifest.rb +448 -503
  39. data/lib/autoproj/metapackage.rb +31 -5
  40. data/lib/autoproj/ops/configuration.rb +46 -45
  41. data/lib/autoproj/ops/import.rb +150 -60
  42. data/lib/autoproj/ops/install.rb +25 -1
  43. data/lib/autoproj/ops/loader.rb +4 -1
  44. data/lib/autoproj/ops/main_config_switcher.rb +4 -4
  45. data/lib/autoproj/ops/snapshot.rb +4 -3
  46. data/lib/autoproj/os_package_installer.rb +105 -46
  47. data/lib/autoproj/os_package_resolver.rb +63 -36
  48. data/lib/autoproj/package_definition.rb +1 -0
  49. data/lib/autoproj/package_managers/apt_dpkg_manager.rb +30 -27
  50. data/lib/autoproj/package_managers/bundler_manager.rb +64 -18
  51. data/lib/autoproj/package_managers/gem_manager.rb +4 -2
  52. data/lib/autoproj/package_managers/manager.rb +26 -7
  53. data/lib/autoproj/package_managers/shell_script_manager.rb +4 -4
  54. data/lib/autoproj/package_managers/zypper_manager.rb +1 -1
  55. data/lib/autoproj/package_manifest.rb +154 -137
  56. data/lib/autoproj/package_selection.rb +16 -2
  57. data/lib/autoproj/package_set.rb +352 -309
  58. data/lib/autoproj/query.rb +13 -1
  59. data/lib/autoproj/system.rb +2 -2
  60. data/lib/autoproj/test.rb +164 -11
  61. data/lib/autoproj/variable_expansion.rb +15 -42
  62. data/lib/autoproj/vcs_definition.rb +93 -76
  63. data/lib/autoproj/version.rb +1 -1
  64. data/lib/autoproj/workspace.rb +116 -80
  65. metadata +10 -2
@@ -0,0 +1,116 @@
1
+ module Autoproj
2
+ module AutobuildExtensions
3
+ module Git
4
+ # Reconfigures this importer to use an already existing checkout located
5
+ # in the given autoproj root
6
+ #
7
+ # @param [Autobuild::Package] the package we are dealing with
8
+ # @param [Autoproj::InstallationManifest] the other root's installation
9
+ # manifest
10
+ def pick_from_autoproj_root(package, installation_manifest)
11
+ other_pkg = installation_manifest[package.name]
12
+ return if !other_pkg || !File.directory?(other_pkg.srcdir)
13
+ self.relocate(other_pkg.srcdir)
14
+ true
15
+ end
16
+
17
+ # Get version information
18
+ #
19
+ # @option options [Boolean] local (true) whether the snapshot should access
20
+ # the remote repository to determine if the local commit is there, and
21
+ # determine what would be the best remote branch, or stick to information
22
+ # that is present locally
23
+ # @option options [Boolean] exact_state (true) whether the snapshot should
24
+ # point to a specific commit (either with a tag or with a commit ID), or
25
+ # only override the branch
26
+ # @return [Hash] the snapshot information, in a format that can be used by
27
+ # {#relocate}
28
+ def snapshot(package, target_dir = nil, only_local: true, exact_state: true)
29
+ if only_local
30
+ snapshot_local(package, exact_state: exact_state)
31
+ else
32
+ snapshot_against_remote(package, exact_state: exact_state)
33
+ end
34
+ end
35
+
36
+ def normalize_branch_name(name)
37
+ if name =~ /^refs\/heads\//
38
+ return name
39
+ else
40
+ "refs/heads/#{name}"
41
+ end
42
+ end
43
+
44
+ # Returns true if the given snapshot information is different from the
45
+ # configured importer state
46
+ #
47
+ # It tests only against the parameters returned by {#snapshot}
48
+ def snapshot_overrides?(snapshot)
49
+ # We have to normalize the branch and tag names
50
+ if snapshot_local = (snapshot['local_branch'] || snapshot['branch'])
51
+ snapshot_local = normalize_branch_name(snapshot_local)
52
+ local_branch = normalize_branch_name(self.local_branch)
53
+ return true if snapshot_local != local_branch
54
+ end
55
+ if snapshot_remote = (snapshot['remote_branch'] || snapshot['branch'])
56
+ snapshot_remote = normalize_branch_name(snapshot_remote)
57
+ remote_branch = normalize_branch_name(self.remote_branch)
58
+ return true if snapshot_remote != remote_branch
59
+ end
60
+ if snapshot_id = snapshot['commit']
61
+ return true if self.commit != snapshot_id
62
+ end
63
+ false
64
+ end
65
+
66
+ # @api private
67
+ def snapshot_against_remote(package, options = Hash.new)
68
+ info = Hash['tag' => nil, 'commit' => nil]
69
+ remote_revname = describe_commit_on_remote(package, 'HEAD', tags: options[:exact_state])
70
+
71
+ case remote_revname
72
+ when /^refs\/heads\/(.*)/
73
+ remote_branch = $1
74
+ if local_branch == remote_branch
75
+ info['branch'] = local_branch
76
+ else
77
+ info['local_branch'] = local_branch
78
+ info['remote_branch'] = remote_branch
79
+ end
80
+ when /^refs\/tags\/(.*)/
81
+ info['tag'] = $1
82
+ else
83
+ info['local_branch'] = local_branch
84
+ info['remote_branch'] = remote_revname
85
+ end
86
+
87
+ if options[:exact_state] && !info['tag']
88
+ info['commit'] = rev_parse(package, 'HEAD')
89
+ end
90
+ info
91
+ end
92
+
93
+ # @api private
94
+ def snapshot_local(package, options = Hash.new)
95
+ info = Hash.new
96
+ if local_branch != remote_branch
97
+ info['local_branch'] = local_branch
98
+ info['remote_branch'] = remote_branch
99
+ else
100
+ info['branch'] = branch
101
+ end
102
+
103
+ if options[:exact_state]
104
+ has_tag, described = describe_rev(package, 'HEAD')
105
+ if has_tag
106
+ info.merge('tag' => described, 'commit' => nil)
107
+ else
108
+ info.merge('tag' => nil, 'commit' => described)
109
+ end
110
+ else
111
+ info
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,159 @@
1
+ module Autoproj
2
+ module AutobuildExtensions
3
+ module Package
4
+ # Tags explicitely added with #add_tag
5
+ attr_reader :added_tags
6
+
7
+ attr_reader :optional_dependencies
8
+
9
+ attr_reader :os_packages
10
+
11
+ attr_writer :ws
12
+ def ws
13
+ @ws ||= Autoproj.workspace
14
+ end
15
+
16
+ # The Autoproj::PackageManifest object that describes this package
17
+ attr_accessor :description
18
+
19
+ def initialize(spec = Hash.new)
20
+ super
21
+ @ws = nil
22
+ @os_packages = Set.new
23
+ @added_tags = Set.new
24
+ @optional_dependencies = Set.new
25
+ @description = PackageManifest.new(self, null: true)
26
+ end
27
+
28
+ # The set of tags for this package. This is an union of the tags
29
+ # contained in +description+ and the ones explicitely added with
30
+ # #add_tag
31
+ def tags
32
+ result = @added_tags.dup
33
+ if description
34
+ result |= description.tags.to_set
35
+ end
36
+ result
37
+ end
38
+
39
+ # Add a tag to the package. Use this if you don't want the tag to be
40
+ # shared with everyone that uses the package (i.e. cannot go in
41
+ # manifest.xml)
42
+ def add_tag(tag)
43
+ @added_tags << tag
44
+ end
45
+
46
+ # True if this package is tagged with the given tag string
47
+ def has_tag?(tag)
48
+ tags.include?(tag.to_s)
49
+ end
50
+
51
+ # Asks autoproj to remove references to the given obsolete oroGen
52
+ # package
53
+ def remove_obsolete_installed_orogen_package(name)
54
+ post_install do
55
+ path = File.join(prefix, 'lib', 'pkgconfig')
56
+ Dir.glob(File.join(path, "#{name}-*.pc")) do |pcfile|
57
+ Autoproj.message " removing obsolete file #{pcfile}", :bold
58
+ FileUtils.rm_f pcfile
59
+ end
60
+ pcfile = File.join(path, "orogen-project-#{name}.pc")
61
+ if File.exist?(pcfile)
62
+ Autoproj.message " removing obsolete file #{pcfile}", :bold
63
+ FileUtils.rm_f pcfile
64
+ end
65
+ end
66
+ end
67
+
68
+ # Asks autoproj to remove the given file in the package's installation
69
+ # prefix
70
+ def remove_obsolete_installed_file(*path)
71
+ post_install do
72
+ path = File.join(prefix, *path)
73
+ if File.exist?(path)
74
+ Autoproj.message " removing obsolete file #{path}", :bold
75
+ FileUtils.rm_f path
76
+ end
77
+ end
78
+ end
79
+
80
+ # Ask autoproj to run the given block after this package has been
81
+ # imported
82
+ def post_import(&block)
83
+ Autoproj.post_import(self, &block)
84
+ end
85
+
86
+ def autoproj_name # :nodoc:
87
+ srcdir.gsub(/^#{Regexp.quote(ws.root_dir)}\//, '')
88
+ end
89
+
90
+ def depends_on(name)
91
+ if name.respond_to?(:name) # probably a Package object
92
+ name = name.name
93
+ end
94
+
95
+ pkg_autobuild, pkg_os = partition_package(name)
96
+ pkg_autobuild.each do |pkg|
97
+ super(pkg)
98
+ end
99
+ @os_packages.merge(pkg_os.to_set)
100
+ end
101
+
102
+ def all_dependencies_with_osdeps(set = Set.new)
103
+ original_set = set.dup
104
+ all_dependencies(set)
105
+ set.dup.each do |dep_pkg_name|
106
+ next if original_set.include?(dep_pkg_name)
107
+ if dep_pkg = ws.manifest.find_autobuild_package(dep_pkg_name)
108
+ set.merge(dep_pkg.os_packages)
109
+ else
110
+ raise ArgumentError, "#{dep_pkg_name}, which is listed as a dependency of #{name}, is not the name of a known package"
111
+ end
112
+ end
113
+ set.merge(os_packages)
114
+ set
115
+ end
116
+
117
+ def depends_on_os_package(name)
118
+ depends_on(name)
119
+ end
120
+
121
+ def remove_dependency(name)
122
+ dependencies.delete name
123
+ optional_dependencies.delete name
124
+ os_packages.delete name
125
+ end
126
+
127
+ def optional_dependency(name)
128
+ optional_dependencies << name
129
+ end
130
+
131
+ def partition_package(pkg_name)
132
+ pkg_autobuild, pkg_osdeps = [], []
133
+ ws.manifest.resolve_package_name(pkg_name).each do |type, dep_name|
134
+ if type == :osdeps
135
+ pkg_osdeps << dep_name
136
+ elsif type == :package
137
+ pkg_autobuild << dep_name
138
+ else raise Autoproj::InternalError, "expected package type to be either :osdeps or :package, got #{type.inspect}"
139
+ end
140
+ end
141
+ return pkg_autobuild, pkg_osdeps
142
+ end
143
+
144
+ def partition_optional_dependencies
145
+ packages, osdeps = [], []
146
+ optional_dependencies.each do |name|
147
+ begin
148
+ pkg_autobuild, pkg_osdeps = partition_package(name)
149
+ packages.concat(pkg_autobuild)
150
+ osdeps.concat(pkg_osdeps)
151
+ rescue Autoproj::PackageNotFound
152
+ # Simply ignore non-existent optional dependencies
153
+ end
154
+ end
155
+ return packages, osdeps
156
+ end
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,11 @@
1
+ module Autoproj
2
+ module AutobuildExtensions
3
+ module SVN
4
+ def snapshot(package, target_dir = nil, options = Hash.new)
5
+ version = svn_revision(package)
6
+ Hash['revision' => version]
7
+ end
8
+ end
9
+ end
10
+ end
11
+
@@ -12,8 +12,8 @@ class Base
12
12
  # @return [Workspace]
13
13
  attr_reader :ws
14
14
 
15
- def initialize(ws = nil)
16
- @ws = (ws || Workspace.default)
15
+ def initialize(ws = Workspace.default)
16
+ @ws = ws
17
17
  end
18
18
 
19
19
  # Normalizes the arguments given by the user on the command line
@@ -56,7 +56,11 @@ def normalize_command_line_package_selection(selection)
56
56
  # resolved
57
57
  def resolve_user_selection(selected_packages, **options)
58
58
  if selected_packages.empty?
59
- return ws.manifest.default_packages
59
+ selection = ws.manifest.default_packages
60
+ if Autoproj.verbose
61
+ Autoproj.message "selected packages: #{selection.each_package_name.to_a.sort.join(", ")}"
62
+ end
63
+ return selection, []
60
64
  end
61
65
  selected_packages = selected_packages.to_set
62
66
 
@@ -65,6 +69,7 @@ def resolve_user_selection(selected_packages, **options)
65
69
 
66
70
  # Try to auto-add stuff if nonresolved
67
71
  nonresolved.delete_if do |sel|
72
+ sel = File.expand_path(sel)
68
73
  next if !File.directory?(sel)
69
74
  while sel != '/'
70
75
  handler, srcdir = Autoproj.package_handler_for(sel)
@@ -73,7 +78,7 @@ def resolve_user_selection(selected_packages, **options)
73
78
  srcdir = File.expand_path(srcdir)
74
79
  relative_to_root = Pathname.new(srcdir).relative_path_from(Pathname.new(ws.root_dir))
75
80
  pkg = ws.in_package_set(ws.manifest.main_package_set, ws.manifest.file) do
76
- send(handler, relative_to_root.to_s)
81
+ send(handler, relative_to_root.to_s, workspace: ws)
77
82
  end
78
83
  ws.setup_package_directories(pkg)
79
84
  selected_packages.select(sel, pkg.name, weak: true)
@@ -85,7 +90,7 @@ def resolve_user_selection(selected_packages, **options)
85
90
  end
86
91
 
87
92
  if Autoproj.verbose
88
- Autoproj.message "will install #{selected_packages.packages.to_a.sort.join(", ")}"
93
+ Autoproj.message "selected packages: #{selected_packages.each_package_name.to_a.sort.join(", ")}"
89
94
  end
90
95
  return selected_packages, nonresolved
91
96
  end
@@ -113,9 +118,10 @@ def resolve_user_selection(selected_packages, **options)
113
118
  # @param [Boolean] recursive whether the resolution should be done
114
119
  # recursively (i.e. dependencies of directly selected packages
115
120
  # should be added) or not
116
- # @param [Boolean] ignore_non_imported_packages whether packages
117
- # that are not imported should simply be ignored. Setting
118
- # checkout_only to true and ignore_non_imported_packages to true
121
+ # @param [Symbol] non_imported_packages whether packages
122
+ # that are not imported should simply be ignored (:ignore),
123
+ # returned (:return) or should be checked out (:checkout). Setting
124
+ # checkout_only to true and this to anything but nil
119
125
  # guarantees in effect that no import operation will take place,
120
126
  # only loading
121
127
  # @return [(Array<String>,Array<String>,PackageSelection)] the list
@@ -123,16 +129,8 @@ def resolve_user_selection(selected_packages, **options)
123
129
  # the package selection resolution object
124
130
  #
125
131
  # @see resolve_user_selection
126
- def resolve_selection(user_selection, checkout_only: true, only_local: false, recursive: true, ignore_non_imported_packages: false)
132
+ def resolve_selection(user_selection, checkout_only: true, only_local: false, recursive: true, non_imported_packages: :ignore)
127
133
  resolved_selection, _ = resolve_user_selection(user_selection, filter: false)
128
- if ignore_non_imported_packages
129
- ws.manifest.each_autobuild_package do |pkg|
130
- if !File.directory?(pkg.srcdir)
131
- ws.manifest.ignore_package(pkg.name)
132
- end
133
- end
134
- end
135
- resolved_selection.filter_excluded_and_ignored_packages(ws.manifest)
136
134
 
137
135
  ops = Ops::Import.new(ws)
138
136
  source_packages, osdep_packages = ops.import_packages(
@@ -140,7 +138,8 @@ def resolve_selection(user_selection, checkout_only: true, only_local: false, re
140
138
  checkout_only: checkout_only,
141
139
  only_local: only_local,
142
140
  recursive: recursive,
143
- warn_about_ignored_packages: false)
141
+ warn_about_ignored_packages: false,
142
+ non_imported_packages: non_imported_packages)
144
143
 
145
144
  return source_packages, osdep_packages, resolved_selection
146
145
  end
@@ -19,8 +19,7 @@ def run(selection, options = Hash.new)
19
19
  packages, _ = normalize_command_line_package_selection(selection)
20
20
  source_packages, * = resolve_selection(
21
21
  selection,
22
- recursive: false,
23
- ignore_non_imported_packages: true)
22
+ recursive: false)
24
23
  if packages.empty?
25
24
  raise ArgumentError, "no packages or OS packages match #{selection.join(" ")}"
26
25
  end
@@ -9,8 +9,7 @@ def validate_options(_unused, options = Hash.new)
9
9
 
10
10
  def run(options = Hash.new)
11
11
  initialize_and_load
12
- finalize_setup(Array.new,
13
- ignore_non_imported_packages: true)
12
+ finalize_setup(Array.new)
14
13
 
15
14
  options = Kernel.validate_options options,
16
15
  shell_helpers: ws.config.shell_helpers?
@@ -5,16 +5,11 @@ module CLI
5
5
  # Base class for CLI tools that do not change the state of the installed
6
6
  # system
7
7
  class InspectionTool < Base
8
- def initialize_and_load(options = Hash.new)
9
- options = Kernel.validate_options options,
10
- mainline: nil
11
-
8
+ def initialize_and_load(mainline: nil)
12
9
  Autoproj.silent do
13
10
  ws.setup
14
- if mainline = options[:mainline]
15
- if mainline == 'mainline' || mainline == 'true'
16
- mainline = true
17
- end
11
+ if mainline == 'mainline' || mainline == 'true'
12
+ mainline = true
18
13
  end
19
14
  ws.load_package_sets(mainline: mainline)
20
15
  ws.config.save
@@ -25,9 +20,9 @@ def initialize_and_load(options = Hash.new)
25
20
  # Finish loading the package information
26
21
  #
27
22
  # @param [Array<String>] packages the list of package names
28
- # @option options ignore_non_imported_packages (true) whether
29
- # packages that are not present on disk should be ignored (true in
30
- # most cases)
23
+ # @param [Symbol] non_imported_packages whether packages that are
24
+ # not yet imported should be ignored (:ignore) or returned
25
+ # (:return).
31
26
  # @option options recursive (true) whether the package resolution
32
27
  # should return the package(s) and their dependencies
33
28
  #
@@ -35,11 +30,7 @@ def initialize_and_load(options = Hash.new)
35
30
  # selected packages, the PackageSelection representing the
36
31
  # selection resolution itself, and a flag telling whether some of
37
32
  # the arguments were pointing within the configuration area
38
- def finalize_setup(packages = [], options = Hash.new)
39
- options = Kernel.validate_options options,
40
- ignore_non_imported_packages: true,
41
- recursive: true
42
-
33
+ def finalize_setup(packages = [], non_imported_packages: :ignore, recursive: true)
43
34
  Autoproj.silent do
44
35
  packages, config_selected = normalize_command_line_package_selection(packages)
45
36
  # Call resolve_user_selection once to auto-add packages, so
@@ -47,7 +38,7 @@ def finalize_setup(packages = [], options = Hash.new)
47
38
  resolve_user_selection(packages)
48
39
  ws.finalize_package_setup
49
40
  source_packages, osdep_packages, resolved_selection =
50
- resolve_selection(packages, options)
41
+ resolve_selection(packages, recursive: recursive, non_imported_packages: non_imported_packages)
51
42
  ws.finalize_setup
52
43
  ws.export_installation_manifest
53
44
  return source_packages, osdep_packages, resolved_selection, config_selected
@@ -57,14 +48,14 @@ def finalize_setup(packages = [], options = Hash.new)
57
48
  def load_all_available_package_manifests
58
49
  # Load the manifest for packages that are already present on the
59
50
  # file system
60
- ws.manifest.packages.each_value do |pkg|
61
- if File.directory?(pkg.autobuild.srcdir)
51
+ ws.manifest.each_autobuild_package do |pkg|
52
+ if pkg.checked_out?
62
53
  begin
63
- ws.manifest.load_package_manifest(pkg.autobuild.name)
54
+ ws.manifest.load_package_manifest(pkg.name)
64
55
  rescue Interrupt
65
56
  raise
66
57
  rescue Exception => e
67
- Autoproj.warn "cannot load package manifest for #{pkg.autobuild.name}: #{e.message}"
58
+ Autoproj.warn "cannot load package manifest for #{pkg.name}: #{e.message}"
68
59
  end
69
60
  end
70
61
  end