autoproj 2.0.0.rc37 → 2.0.0.rc38

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.
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
@@ -1,113 +1,170 @@
1
- require 'autoproj/cli/base'
1
+ require 'autoproj/cli/inspection_tool'
2
2
 
3
3
  module Autoproj
4
4
  module CLI
5
- class Locate < Base
5
+ # Deal with locating a package source or build directory in an existing
6
+ # workspace
7
+ #
8
+ # It is based on a installation manifest file, a YAML file generated to
9
+ # list that information and thus avoid loading the Autoproj
10
+ # configuration (which takes fairly long).
11
+ class Locate < InspectionTool
6
12
  class NotFound < RuntimeError; end
7
13
  class AmbiguousSelection < RuntimeError; end
8
14
 
9
- attr_reader :installation_manifest
10
-
11
- def initialize(ws = nil)
12
- super
13
- self.ws.load_config
14
-
15
- path = InstallationManifest.path_for_root(self.ws.root_dir)
16
- if !File.file?(path)
17
- raise ConfigError, "the installation manifest is not present, please run autoproj envsh to generate it"
15
+ attr_reader :packages
16
+ attr_reader :package_sets
17
+
18
+ # Create the locate CLI interface
19
+ #
20
+ # @param [Workspace] ws the workspace we're working on
21
+ # @param [InstallationManifest,nil] installation_manifest the
22
+ # manifest. If nil, loads the whole autoproj configuration and
23
+ # rebuilds the manifest
24
+ def initialize(ws = Workspace.default, installation_manifest: try_loading_installation_manifest(ws))
25
+ super(ws)
26
+ ws.load_config
27
+
28
+ if installation_manifest
29
+ update_from_installation_manifest(installation_manifest)
18
30
  end
31
+ end
19
32
 
20
- @installation_manifest = Autoproj::InstallationManifest.new(path)
21
- installation_manifest.load
33
+ def update_from_installation_manifest(installation_manifest)
34
+ @packages = installation_manifest.each_package.to_a
35
+ @package_sets = installation_manifest.each_package_set.to_a
22
36
  end
23
37
 
24
- def validate_options(selected, options)
25
- selected, options = super
26
- return selected.first, options
38
+ # Load the installation manifest
39
+ def try_loading_installation_manifest(ws = self.ws)
40
+ Autoproj::InstallationManifest.from_workspace_root(ws.root_dir)
41
+ rescue ConfigError
27
42
  end
28
43
 
29
- def result_value(pkg, options)
30
- if options[:build]
31
- if pkg.builddir
32
- pkg.builddir
33
- else
34
- raise ConfigError, "#{pkg.name} does not have a build directory"
35
- end
36
- else
37
- pkg.srcdir
44
+ # Find a package set that matches a given selection
45
+ #
46
+ # @param [String] selection a string that is matched against the
47
+ # package set name and its various directories. Directories are
48
+ # matched against the full path and must end with /
49
+ # @return [PackageSet,nil]
50
+ def find_package_set(selection)
51
+ package_sets.find do |pkg_set|
52
+ name = pkg_set.name
53
+ name == selection ||
54
+ selection.start_with?("#{pkg_set.raw_local_dir}/") ||
55
+ selection.start_with?("#{pkg_set.user_local_dir}/")
38
56
  end
39
57
  end
40
58
 
41
- def run(selection, options = Hash.new)
42
- if !selection
43
- if options[:build]
44
- puts ws.prefix_dir
45
- else
46
- puts ws.root_dir
59
+ def find_packages(selection)
60
+ selection_rx = Regexp.new(Regexp.quote(selection))
61
+ candidates = []
62
+ packages.each do |pkg|
63
+ name = pkg.name
64
+ if name == selection || selection.start_with?("#{pkg.srcdir}/")
65
+ return [pkg]
66
+ elsif pkg.respond_to?(:builddir) && pkg.builddir && selection.start_with?("#{pkg.builddir}/")
67
+ return [pkg]
68
+ elsif name =~ selection_rx
69
+ candidates << pkg
47
70
  end
48
- return
49
71
  end
72
+ return candidates
73
+ end
50
74
 
51
- if File.directory?(selection)
52
- selection = File.expand_path(selection)
53
- end
75
+ def find_packages_with_directory_shortnames(selection)
76
+ *directories, basename = *selection.split('/')
77
+ dirname_rx = directories.
78
+ map { |d| "#{Regexp.quote(d)}\\w*" }.
79
+ join("/")
80
+
81
+ rx = Regexp.new("#{dirname_rx}/#{Regexp.quote(basename)}")
82
+ rx_strict = Regexp.new("#{dirname_rx}/#{Regexp.quote(basename)}$")
54
83
 
55
- selection_rx = Regexp.new(Regexp.quote(selection))
56
84
  candidates = []
57
- installation_manifest.each do |pkg|
85
+ candidates_strict = []
86
+ packages.each do |pkg|
58
87
  name = pkg.name
59
- if name == selection || pkg.srcdir == selection
60
- puts result_value(pkg, options)
61
- return
62
- elsif name =~ selection_rx || selection.start_with?(pkg.srcdir) || (selection.start_with?(pkg.builddir) if pkg.builddir)
88
+ if name =~ rx
63
89
  candidates << pkg
64
90
  end
91
+ if name =~ rx_strict
92
+ candidates_strict << pkg
93
+ end
65
94
  end
66
95
 
67
- if candidates.empty?
68
- # Try harder. Match directory prefixes
69
- directories = selection.split('/')
70
- rx = directories.
71
- map { |d| "#{Regexp.quote(d)}\\w*" }.
72
- join("/")
73
- rx = Regexp.new(rx)
74
-
75
- rx_strict = directories[0..-2].
76
- map { |d| "#{Regexp.quote(d)}\\w*" }.
77
- join("/")
78
- rx_strict = Regexp.new("#{rx_strict}/#{Regexp.quote(directories.last)}$")
79
-
80
- candidates_strict = []
81
- installation_manifest.each do |pkg|
82
- name = pkg.name
83
- if name =~ rx
84
- candidates << pkg
85
- end
86
- if name =~ rx_strict
87
- candidates_strict << pkg
88
- end
96
+ if candidates.size > 1 && candidates_strict.size == 1
97
+ candidates_strict
98
+ else
99
+ candidates
100
+ end
101
+ end
102
+
103
+ def initialize_from_workspace
104
+ initialize_and_load
105
+ finalize_setup # this exports the manifest
106
+
107
+ @packages = ws.manifest.each_autobuild_package.to_a
108
+ @package_sets = ws.manifest.each_package_set.to_a
109
+ end
110
+
111
+ def run(selections, cache: !!packages, build: false, prefix: false)
112
+ if !cache
113
+ initialize_from_workspace
114
+ end
115
+
116
+ if selections.empty?
117
+ if prefix || build
118
+ puts ws.prefix_dir
119
+ else
120
+ puts ws.root_dir
89
121
  end
122
+ end
90
123
 
91
- if candidates.size > 1 && candidates_strict.size == 1
92
- candidates = candidates_strict
124
+ selections.each do |string|
125
+ if File.directory?(string)
126
+ string = "#{File.expand_path(string)}/"
93
127
  end
128
+ puts location_of(string, build: build, prefix: prefix)
129
+ end
130
+ end
131
+
132
+ def location_of(selection, prefix: false, build: false)
133
+ if pkg_set = find_package_set(selection)
134
+ return pkg_set.user_local_dir
94
135
  end
95
136
 
96
- if candidates.size > 1
137
+ matching_packages = find_packages(selection)
138
+ if matching_packages.empty?
139
+ matching_packages = find_packages_with_directory_shortnames(selection)
140
+ end
141
+
142
+ if matching_packages.size > 1
97
143
  # If there is more than one candidate, check if there are some that are not
98
144
  # present on disk
99
- present = candidates.find_all { |pkg| File.directory?(pkg.srcdir) }
145
+ present = matching_packages.find_all { |pkg| File.directory?(pkg.srcdir) }
100
146
  if present.size == 1
101
- candidates = present
147
+ matching_packages = present
102
148
  end
103
149
  end
104
150
 
105
- if candidates.empty?
106
- raise ArgumentError, "cannot find #{selection} in the current autoproj installation"
107
- elsif candidates.size > 1
108
- raise ArgumentError, "multiple packages match #{selection} in the current autoproj installation: #{candidates.map(&:name).sort.join(", ")}"
151
+ if matching_packages.empty?
152
+ raise NotFound, "cannot find '#{selection}' in the current autoproj installation"
153
+ elsif matching_packages.size > 1
154
+ raise AmbiguousSelection, "multiple packages match '#{selection}' in the current autoproj installation: #{matching_packages.map(&:name).sort.join(", ")}"
109
155
  else
110
- puts result_value(candidates.first, options)
156
+ pkg = matching_packages.first
157
+ if prefix
158
+ pkg.prefix
159
+ elsif build
160
+ if pkg.respond_to?(:builddir) && pkg.builddir
161
+ pkg.builddir
162
+ else
163
+ raise ArgumentError, "#{pkg.name} does not have a build directory"
164
+ end
165
+ else
166
+ pkg.srcdir
167
+ end
111
168
  end
112
169
  end
113
170
  end
@@ -1,6 +1,7 @@
1
1
  require 'thor'
2
2
  require 'tty/color'
3
3
  require 'autoproj/cli/main_test'
4
+ require 'autoproj/cli/main_plugin'
4
5
 
5
6
  module Autoproj
6
7
  module CLI
@@ -27,7 +28,7 @@ class Main < Thor
27
28
  default: TTY::Color.color?
28
29
 
29
30
  no_commands do
30
- def run_autoproj_cli(filename, classname, report_options, *args)
31
+ def run_autoproj_cli(filename, classname, report_options, *args, **extra_options)
31
32
  require "autoproj/cli/#{filename}"
32
33
  Autoproj.report(Hash[silent: !options[:debug], debug: options[:debug]].merge(report_options)) do
33
34
  options = self.options.dup
@@ -37,7 +38,7 @@ def run_autoproj_cli(filename, classname, report_options, *args)
37
38
  options[:only_local] = options.delete('local')
38
39
  end
39
40
  cli = CLI.const_get(classname).new
40
- run_args = cli.validate_options(args, options)
41
+ run_args = cli.validate_options(args, options.merge(extra_options))
41
42
  cli.run(*run_args)
42
43
  end
43
44
  end
@@ -54,7 +55,7 @@ def bootstrap(*args)
54
55
  if !File.directory?(File.join(Dir.pwd, '.autoproj'))
55
56
  require 'autoproj/ops/install'
56
57
  ops = Autoproj::Ops::Install.new(Dir.pwd)
57
- remaining = ops.parse_options(args)
58
+ ops.parse_options(args)
58
59
  ops.run
59
60
  exec Gem.ruby, $0, 'bootstrap', *args
60
61
  end
@@ -75,6 +76,9 @@ def envsh
75
76
  desc: "use the VCS information as 'versions --no-local' would detect it instead of the one in the configuration"
76
77
  option :parallel, aliases: :p, type: :numeric,
77
78
  desc: 'maximum number of parallel jobs'
79
+ option :deps, type: :boolean,
80
+ desc: 'whether only the status of the given packages should be displayed, or of their dependencies as well',
81
+ default: true
78
82
  def status(*packages)
79
83
  run_autoproj_cli(:status, :Status, Hash[], *packages)
80
84
  end
@@ -163,10 +167,14 @@ def clean(*packages)
163
167
  end
164
168
 
165
169
  desc 'locate [PACKAGE]', 'return the path to the given package, or the path to the root if no packages are given on the command line'
170
+ option :cache, type: :boolean,
171
+ desc: 'controls whether the resolution should be done by loading the whole configuration (false, slow) or through a cache file (the default)'
172
+ option :prefix, aliases: :p, type: :boolean,
173
+ desc: "outputs the package's prefix directory instead of its source directory"
166
174
  option :build, aliases: :b, type: :boolean,
167
175
  desc: "outputs the package's build directory instead of its source directory"
168
- def locate(package = nil)
169
- run_autoproj_cli(:locate, :Locate, Hash[], *Array(package))
176
+ def locate(*packages)
177
+ run_autoproj_cli(:locate, :Locate, Hash[], *packages)
170
178
  end
171
179
 
172
180
  desc 'reconfigure', 'pass through all configuration questions'
@@ -184,6 +192,9 @@ def reconfigure
184
192
  desc: "compare to the given baseline. if 'true', the comparison will ignore any override, otherwise it will take into account overrides only up to the given package set"
185
193
  option :env, type: :boolean,
186
194
  desc: "display the package's own environment", default: false
195
+ option :short, desc: 'display a package summary with one package line'
196
+ option :recursive, desc: 'display the package and their dependencies (the default is to only display selected packages)',
197
+ type: :boolean, default: false
187
198
  def show(*packages)
188
199
  run_autoproj_cli(:show, :Show, Hash[], *packages)
189
200
  end
@@ -335,6 +346,21 @@ def install_stage2(root_dir, *vars)
335
346
  end
336
347
  ops.stage2(*vars)
337
348
  end
349
+
350
+ desc 'plugin', 'interface to manage autoproj plugins'
351
+ subcommand 'plugin', MainPlugin
352
+
353
+ desc 'patch', 'applies patches necessary for the selected package',
354
+ hide: true
355
+ def patch(*packages)
356
+ run_autoproj_cli(:patcher, :Patcher, Hash[], *packages, patch: true)
357
+ end
358
+
359
+ desc 'unpatch', 'remove any patch applied on the selected package',
360
+ hide: true
361
+ def unpatch(*packages)
362
+ run_autoproj_cli(:patcher, :Patcher, Hash[], *packages, patch: false)
363
+ end
338
364
  end
339
365
  end
340
366
  end
@@ -0,0 +1,79 @@
1
+ module Autoproj
2
+ module CLI
3
+ class MainPlugin < Thor
4
+ namespace 'plugin'
5
+
6
+ no_commands do
7
+ def ws
8
+ @ws ||= Workspace.from_pwd
9
+ end
10
+
11
+ def install_plugins
12
+ ws.load_config
13
+ ws.update_autoproj(restart_on_update: false)
14
+ end
15
+
16
+ def read_plugin_list
17
+ ws.load_config
18
+ ws.config.get('plugins', Hash.new)
19
+ end
20
+
21
+ def write_plugin_list(plugins)
22
+ ws.load_config
23
+ ws.config.set('plugins', plugins)
24
+ ws.save_config
25
+ end
26
+ end
27
+
28
+ desc 'install NAME', 'install or upgrade an autoproj plugin'
29
+ option :version, desc: 'a gem version constraint',
30
+ type: 'string', default: '>= 0'
31
+ option :git, desc: 'checkout a git repository instead of downloading the gem',
32
+ type: 'string'
33
+ option :path, desc: 'use the plugin that is already present on this path',
34
+ type: 'string'
35
+ def install(name)
36
+ require 'autoproj'
37
+
38
+ gem_options = Hash.new
39
+ if options[:git] && options[:path]
40
+ raise ArgumentError, "you can provide only one of --git or --path"
41
+ elsif options[:git]
42
+ gem_options[:git] = options[:git]
43
+ elsif options[:path]
44
+ gem_options[:path] = options[:path]
45
+ end
46
+
47
+ plugins = read_plugin_list
48
+ updated_plugins = plugins.merge(name => [options[:version], gem_options])
49
+ write_plugin_list(updated_plugins)
50
+ begin
51
+ install_plugins
52
+ rescue Exception
53
+ write_plugin_list(plugins)
54
+ install_plugins
55
+ raise
56
+ end
57
+ end
58
+
59
+ desc 'list', 'list installed plugins'
60
+ def list
61
+ require 'autoproj'
62
+ read_plugin_list.sort_by(&:first).each do |name, (version, options)|
63
+ args = [version, *options.map { |k, v| "#{k}: \"#{v}\"" }]
64
+ puts "#{name}: #{args.join(", ")}"
65
+ end
66
+ end
67
+
68
+ desc 'remove NAME', 'uninstall a plugin'
69
+ def remove(name)
70
+ require 'autoproj'
71
+ plugins = read_plugin_list
72
+ updated_plugins = plugins.dup
73
+ updated_plugins.delete(name)
74
+ write_plugin_list(updated_plugins)
75
+ install_plugins
76
+ end
77
+ end
78
+ end
79
+ end
@@ -4,13 +4,21 @@ class MainTest < Thor
4
4
  namespace 'test'
5
5
 
6
6
  default_command 'exec'
7
+
8
+ no_commands do
9
+ def report(report_options = Hash.new)
10
+ Autoproj.report(Hash[silent: !options[:debug], debug: options[:debug]].merge(report_options)) do
11
+ yield
12
+ end
13
+ end
14
+ end
7
15
 
8
16
  desc 'enable [PACKAGES]', 'enable tests for the given packages (or for all packages if none are given)'
9
17
  option :deps, type: :boolean, default: false,
10
18
  desc: 'controls whether the dependencies of the packages given on the command line should be enabled as well (the default is not)'
11
19
  def enable(*packages)
12
20
  require 'autoproj/cli/test'
13
- Autoproj.report(silent: true) do
21
+ report(silent: true) do
14
22
  cli = Test.new
15
23
  args = cli.validate_options(packages, options)
16
24
  cli.enable(*args)
@@ -22,7 +30,7 @@ def enable(*packages)
22
30
  desc: 'controls whether the dependencies of the packages given on the command line should be disabled as well (the default is not)'
23
31
  def disable(*packages)
24
32
  require 'autoproj/cli/test'
25
- Autoproj.report(silent: true) do
33
+ report(silent: true) do
26
34
  cli = Test.new
27
35
  args = cli.validate_options(packages, options)
28
36
  cli.disable(*args)
@@ -30,11 +38,11 @@ def disable(*packages)
30
38
  end
31
39
 
32
40
  desc 'list [PACKAGES]', 'show test enable/disable status for the given packages (or all packages if none are given)'
33
- option :deps, type: :boolean, default: false,
41
+ option :deps, type: :boolean, default: true,
34
42
  desc: 'controls whether the dependencies of the packages given on the command line should be disabled as well (the default is not)'
35
43
  def list(*packages)
36
44
  require 'autoproj/cli/test'
37
- Autoproj.report(silent: true) do
45
+ report(silent: true) do
38
46
  cli = Test.new
39
47
  args = cli.validate_options(packages, options)
40
48
  cli.list(*args)
@@ -44,10 +52,16 @@ def list(*packages)
44
52
  desc 'exec [PACKAGES]', 'execute the tests for the given packages, or all if no packages are given on the command line'
45
53
  option :deps, type: :boolean, default: false,
46
54
  desc: 'controls whether to execute the tests of the dependencies of the packages given on the command line (the default is not)'
55
+ option :fail, type: :boolean, default: true,
56
+ desc: 'return with a nonzero exit code if the test does not pass'
57
+ option :coverage, type: :boolean, default: false,
58
+ desc: 'whether code coverage should be generated if possible'
47
59
  def exec(*packages)
48
60
  require 'autoproj/cli/test'
49
- Autoproj.report do
61
+ report do
50
62
  cli = Test.new
63
+ Autobuild.pass_test_errors = options[:fail]
64
+ Autobuild::TestUtility.coverage_enabled = options[:coverage]
51
65
  args = cli.validate_options(packages, options)
52
66
  cli.run(*args)
53
67
  end