autoproj 2.10.1 → 2.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -8
  3. data/.travis.yml +5 -3
  4. data/autoproj.gemspec +7 -6
  5. data/bin/alog +1 -0
  6. data/bin/autoproj +1 -1
  7. data/bin/autoproj_bootstrap +149 -86
  8. data/bin/autoproj_bootstrap.in +9 -7
  9. data/bin/autoproj_install +148 -82
  10. data/bin/autoproj_install.in +8 -3
  11. data/lib/autoproj.rb +3 -0
  12. data/lib/autoproj/aruba_minitest.rb +15 -0
  13. data/lib/autoproj/autobuild_extensions/dsl.rb +61 -27
  14. data/lib/autoproj/base.rb +35 -6
  15. data/lib/autoproj/cli/base.rb +1 -1
  16. data/lib/autoproj/cli/build.rb +9 -3
  17. data/lib/autoproj/cli/cache.rb +79 -7
  18. data/lib/autoproj/cli/doc.rb +4 -18
  19. data/lib/autoproj/cli/inspection_tool.rb +5 -6
  20. data/lib/autoproj/cli/main.rb +41 -18
  21. data/lib/autoproj/cli/main_doc.rb +86 -0
  22. data/lib/autoproj/cli/main_plugin.rb +3 -0
  23. data/lib/autoproj/cli/main_test.rb +15 -0
  24. data/lib/autoproj/cli/show.rb +12 -18
  25. data/lib/autoproj/cli/status.rb +15 -9
  26. data/lib/autoproj/cli/test.rb +13 -84
  27. data/lib/autoproj/cli/update.rb +77 -19
  28. data/lib/autoproj/cli/utility.rb +136 -0
  29. data/lib/autoproj/configuration.rb +28 -4
  30. data/lib/autoproj/default.osdeps +18 -0
  31. data/lib/autoproj/installation_manifest.rb +7 -5
  32. data/lib/autoproj/manifest.rb +15 -21
  33. data/lib/autoproj/ops/build.rb +23 -27
  34. data/lib/autoproj/ops/cache.rb +151 -33
  35. data/lib/autoproj/ops/cached_env.rb +2 -2
  36. data/lib/autoproj/ops/import.rb +146 -80
  37. data/lib/autoproj/ops/install.rb +140 -79
  38. data/lib/autoproj/ops/phase_reporting.rb +49 -0
  39. data/lib/autoproj/ops/snapshot.rb +2 -1
  40. data/lib/autoproj/ops/tools.rb +2 -2
  41. data/lib/autoproj/os_package_installer.rb +19 -11
  42. data/lib/autoproj/package_definition.rb +29 -10
  43. data/lib/autoproj/package_managers/apt_dpkg_manager.rb +49 -28
  44. data/lib/autoproj/package_managers/bundler_manager.rb +257 -87
  45. data/lib/autoproj/package_managers/homebrew_manager.rb +2 -2
  46. data/lib/autoproj/package_managers/shell_script_manager.rb +44 -24
  47. data/lib/autoproj/package_manifest.rb +49 -34
  48. data/lib/autoproj/package_set.rb +48 -29
  49. data/lib/autoproj/repository_managers/apt.rb +0 -1
  50. data/lib/autoproj/test.rb +29 -10
  51. data/lib/autoproj/variable_expansion.rb +3 -1
  52. data/lib/autoproj/vcs_definition.rb +30 -15
  53. data/lib/autoproj/version.rb +1 -1
  54. data/lib/autoproj/workspace.rb +55 -13
  55. metadata +32 -28
@@ -1,24 +1,10 @@
1
- require 'autoproj/cli/inspection_tool'
1
+ require 'autoproj/cli/utility'
2
2
 
3
3
  module Autoproj
4
4
  module CLI
5
- class Doc < InspectionTool
6
- def validate_options(packages, options)
7
- packages, options = super
8
- if options[:no_deps_shortcut]
9
- options[:deps] = false
10
- end
11
- return packages, options
12
- end
13
-
14
- def run(user_selection, deps: true)
15
- initialize_and_load
16
- packages, _ =
17
- finalize_setup(user_selection, recursive: deps)
18
- packages.each do |pkg|
19
- ws.manifest.find_autobuild_package(pkg).disable_phases('import', 'prepare', 'install')
20
- end
21
- Autobuild.apply(packages, "autoproj-doc", ['doc'])
5
+ class Doc < Utility
6
+ def initialize(ws = Workspace.default, name: 'doc')
7
+ super
22
8
  end
23
9
  end
24
10
  end
@@ -8,9 +8,7 @@ class InspectionTool < Base
8
8
  def initialize_and_load(mainline: nil)
9
9
  Autoproj.silent do
10
10
  ws.setup
11
- if mainline == 'mainline' || mainline == 'true'
12
- mainline = true
13
- end
11
+ mainline = true if %w[mainline true].include?(mainline)
14
12
  ws.load_package_sets(mainline: mainline)
15
13
  ws.config.save
16
14
  ws.setup_all_package_directories
@@ -22,7 +20,7 @@ def initialize_and_load(mainline: nil)
22
20
  # @param [Array<String>] packages the list of package names
23
21
  # @param [Symbol] non_imported_packages whether packages that are
24
22
  # not yet imported should be ignored (:ignore) or returned
25
- # (:return).
23
+ # (:return).
26
24
  # @option options recursive (true) whether the package resolution
27
25
  # should return the package(s) and their dependencies
28
26
  #
@@ -32,7 +30,8 @@ def initialize_and_load(mainline: nil)
32
30
  # the arguments were pointing within the configuration area
33
31
  def finalize_setup(packages = [], non_imported_packages: :ignore, recursive: true, auto_exclude: false)
34
32
  Autoproj.silent do
35
- packages, config_selected = normalize_command_line_package_selection(packages)
33
+ packages, config_selected =
34
+ normalize_command_line_package_selection(packages)
36
35
  # Call resolve_user_selection once to auto-add packages, so
37
36
  # that they're available to e.g. overrides.rb
38
37
  resolve_user_selection(packages)
@@ -41,7 +40,7 @@ def finalize_setup(packages = [], non_imported_packages: :ignore, recursive: tru
41
40
  resolve_selection(packages, recursive: recursive, non_imported_packages: non_imported_packages, auto_exclude: auto_exclude)
42
41
  ws.finalize_setup
43
42
  ws.export_installation_manifest
44
- return source_packages, osdep_packages, resolved_selection, config_selected
43
+ [source_packages, osdep_packages, resolved_selection, config_selected]
45
44
  end
46
45
  end
47
46
  end
@@ -1,5 +1,6 @@
1
1
  require 'thor'
2
2
  require 'tty/color'
3
+ require 'autoproj/cli/main_doc'
3
4
  require 'autoproj/cli/main_test'
4
5
  require 'autoproj/cli/main_plugin'
5
6
  require 'autoproj/cli/main_global'
@@ -37,6 +38,10 @@ class Main < Thor
37
38
  stop_on_unknown_option! :exec
38
39
  check_unknown_options! except: :exec
39
40
 
41
+ def self.exit_on_failure?
42
+ true
43
+ end
44
+
40
45
  class << self
41
46
  # @api private
42
47
  #
@@ -129,8 +134,9 @@ def run_autoproj_cli(filename, classname, report_options, *args, tool_failure_mo
129
134
  end
130
135
  cli = CLI.const_get(classname).new
131
136
  begin
132
- run_args = cli.validate_options(args, options.merge(extra_options))
133
- cli.run(*run_args)
137
+ *run_args, kw = cli.validate_options(args, options.merge(extra_options))
138
+ kw = (kw || {}).transform_keys(&:to_sym)
139
+ cli.run(*run_args, **kw)
134
140
  ensure
135
141
  cli.notify_env_sh_updated if cli.respond_to?(:notify_env_sh_updated)
136
142
  end
@@ -183,15 +189,6 @@ def status(*packages)
183
189
  run_autoproj_cli(:status, :Status, Hash[], *packages)
184
190
  end
185
191
 
186
- desc 'doc [PACKAGES]', 'generate API documentation for packages that support it'
187
- option :deps, type: :boolean, default: true,
188
- desc: 'control whether documentation should be generated only for the packages given on the command line, or also for their dependencies. -n is a shortcut for --no-deps'
189
- option :no_deps_shortcut, hide: true, aliases: '-n', type: :boolean,
190
- desc: 'provide -n for --no-deps'
191
- def doc(*packages)
192
- run_autoproj_cli(:doc, :Doc, Hash[], *packages)
193
- end
194
-
195
192
  desc 'update [PACKAGES]', 'update packages'
196
193
  option :aup, default: false, hide: true, type: :boolean,
197
194
  desc: 'behave like aup'
@@ -232,6 +229,8 @@ def doc(*packages)
232
229
  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"
233
230
  option :auto_exclude, type: :boolean,
234
231
  desc: 'if true, packages that fail to import will be excluded from the build'
232
+ option :ask, type: :boolean, default: false,
233
+ desc: 'ask whether each package should or should not be updated'
235
234
  def update(*packages)
236
235
  report_options = Hash[silent: false, on_package_failures: default_report_on_package_failures]
237
236
  if options[:auto_exclude]
@@ -304,13 +303,34 @@ def build(*packages)
304
303
  end
305
304
  end
306
305
 
307
- desc 'cache CACHE_DIR', 'create or update a cache directory that can be given to AUTOBUILD_CACHE_DIR'
308
- option :keep_going, aliases: :k,
309
- desc: 'do not stop on errors'
310
- option :checkout_only, aliases: :c, type: :boolean, default: false,
311
- desc: "only checkout packages, do not update already-cached ones"
312
- option :all, type: :boolean, default: true,
313
- desc: "cache all defined packages (the default) or only the selected ones"
306
+ desc 'cache CACHE_DIR', 'create or update a cache directory that '\
307
+ 'can be given to AUTOBUILD_CACHE_DIR'
308
+ option :keep_going,
309
+ aliases: :k,
310
+ desc: 'do not stop on errors'
311
+ option :checkout_only,
312
+ aliases: :c, type: :boolean, default: false,
313
+ desc: 'only checkout packages, do not update already-cached ones'
314
+ option :all,
315
+ type: :boolean, default: true,
316
+ desc: 'cache all defined packages (the default), '\
317
+ ' or only the selected ones'
318
+ option :packages,
319
+ type: :boolean, default: true,
320
+ desc: 'update the package cache'
321
+ option :gems,
322
+ type: :boolean, default: false,
323
+ desc: 'update the gems cache'
324
+ option :gems_compile_force,
325
+ type: :boolean, default: false,
326
+ desc: 'with --gems-compile, recompile existing gems as well'
327
+ option :gems_compile,
328
+ type: :array,
329
+ desc: 'pre-compile the following gems. This requires gem-compiler '\
330
+ 'to be available in the workspace. Use GEM_NAME+ARTIFACT'\
331
+ '[+ARTIFACT] to add files or directories to the precompiled '\
332
+ 'gems beyond what gem-compiler auto-adds (which is mostly '\
333
+ 'dynamic libraries)'
314
334
  def cache(*args)
315
335
  run_autoproj_cli(:cache, :Cache, Hash[], *args)
316
336
  end
@@ -360,6 +380,9 @@ def reconfigure
360
380
  desc 'test', 'interface for running tests'
361
381
  subcommand 'test', MainTest
362
382
 
383
+ desc 'doc', 'interface for generating documentation'
384
+ subcommand 'doc', MainDoc
385
+
363
386
  desc 'show [PACKAGES]', 'show informations about package(s)'
364
387
  option :mainline, type: :string,
365
388
  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"
@@ -0,0 +1,86 @@
1
+ module Autoproj
2
+ module CLI
3
+ class MainDoc < Thor
4
+ namespace 'doc'
5
+
6
+ default_command 'exec'
7
+
8
+ no_commands do
9
+ def report(report_options = Hash.new)
10
+ options = self.options.merge(parent_options)
11
+ extra_options = Hash.new
12
+ if Autobuild::Subprocess.transparent_mode = options[:tool]
13
+ Autobuild.silent = true
14
+ Autobuild.color = false
15
+ report_options[:silent] = true
16
+ report_options[:on_package_failures] = :exit_silent
17
+ extra_options[:silent] = true
18
+ end
19
+ Autoproj.report(**Hash[debug: options[:debug]].merge(report_options)) do
20
+ yield(extra_options)
21
+ end
22
+ end
23
+ end
24
+
25
+ desc 'enable [PACKAGES]', 'enable docs for the given packages (or for all packages if none are given)'
26
+ option :deps, type: :boolean, default: false,
27
+ desc: 'controls whether the dependencies of the packages given on the command line should be enabled as well (the default is not)'
28
+ def enable(*packages)
29
+ require 'autoproj/cli/doc'
30
+ report(silent: true) do
31
+ cli = Doc.new
32
+ args = cli.validate_options(packages, options)
33
+ cli.enable(*args)
34
+ end
35
+ end
36
+
37
+ desc 'disable [PACKAGES]', 'disable docs for the given packages (or for all packages if none are given)'
38
+ option :deps, type: :boolean, default: false,
39
+ desc: 'controls whether the dependencies of the packages given on the command line should be disabled as well (the default is not)'
40
+ def disable(*packages)
41
+ require 'autoproj/cli/doc'
42
+ report(silent: true) do
43
+ cli = Doc.new
44
+ args = cli.validate_options(packages, options)
45
+ cli.disable(*args)
46
+ end
47
+ end
48
+
49
+ desc 'list [PACKAGES]', 'show doc enable/disable status for the given packages (or all packages if none are given)'
50
+ option :deps, type: :boolean, default: true,
51
+ desc: 'controls whether the dependencies of the packages given on the command line should be disabled as well (the default is not)'
52
+ def list(*packages)
53
+ require 'autoproj/cli/doc'
54
+ report(silent: true) do
55
+ cli = Doc.new
56
+ args = cli.validate_options(packages, options)
57
+ cli.list(*args)
58
+ end
59
+ end
60
+
61
+ desc 'exec [PACKAGES]', 'generate documentation for the given packages, or all if no packages are given on the command line'
62
+ option :deps, type: :boolean, default: false,
63
+ desc: 'controls whether to generate documentation of the dependencies of the packages given on the command line (the default is not)'
64
+ option :no_deps_shortcut, hide: true, aliases: '-n', type: :boolean,
65
+ desc: 'provide -n for --no-deps'
66
+ option :parallel, aliases: :p, type: :numeric,
67
+ desc: 'maximum number of parallel jobs'
68
+ option :tool, type: :boolean, default: false,
69
+ desc: "run in tool mode, which do not redirect the subcommand's outputs"
70
+ option :color, type: :boolean, default: TTY::Color.color?,
71
+ desc: 'enables or disables colored display (enabled by default if the terminal supports it)'
72
+ option :progress, type: :boolean, default: TTY::Color.color?,
73
+ desc: 'enables or disables progress display (enabled by default if the terminal supports it)'
74
+ def exec(*packages)
75
+ require 'autoproj/cli/doc'
76
+ options = self.options.merge(parent_options)
77
+ report do |extra_options|
78
+ cli = Doc.new
79
+ options.delete(:tool)
80
+ args = cli.validate_options(packages, options.merge(extra_options))
81
+ cli.run(*args)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -30,6 +30,8 @@ def write_plugin_list(plugins)
30
30
  type: 'string', default: '>= 0'
31
31
  option :git, desc: 'checkout a git repository instead of downloading the gem',
32
32
  type: 'string'
33
+ option :branch, desc: 'choose the branch that should be checked out with --git',
34
+ type: 'string', default: 'master'
33
35
  option :path, desc: 'use the plugin that is already present on this path',
34
36
  type: 'string'
35
37
  def install(name)
@@ -40,6 +42,7 @@ def install(name)
40
42
  raise CLIInvalidArguments, "you can provide only one of --git or --path"
41
43
  elsif options[:git]
42
44
  gem_options[:git] = options[:git]
45
+ gem_options[:branch] = options[:branch]
43
46
  elsif options[:path]
44
47
  gem_options[:path] = options[:path]
45
48
  end
@@ -22,6 +22,21 @@ def report(report_options = Hash.new)
22
22
  end
23
23
  end
24
24
 
25
+ desc 'default [on|off]', 'set whether tests are enabled or disabled by default, without touching existing settings'
26
+ def default(on_or_off)
27
+ require 'autoproj/cli/test'
28
+ report(silent: true) do
29
+ cli = Test.new
30
+ args = cli.validate_options([], options)
31
+ enabled = case on_or_off
32
+ when 'on' then true
33
+ when 'off' then false
34
+ else raise ArgumentError, "expected 'on' or 'off'"
35
+ end
36
+ cli.default(enabled)
37
+ end
38
+ end
39
+
25
40
  desc 'enable [PACKAGES]', 'enable tests for the given packages (or for all packages if none are given)'
26
41
  option :deps, type: :boolean, default: false,
27
42
  desc: 'controls whether the dependencies of the packages given on the command line should be enabled as well (the default is not)'
@@ -17,7 +17,8 @@ def run(user_selection, short: false, recursive: false, mainline: false, env: fa
17
17
  source_packages, osdep_packages, * =
18
18
  finalize_setup(user_selection, recursive: recursive, non_imported_packages: :return)
19
19
  else
20
- source_packages, osdep_packages = Array.new, Array.new
20
+ source_packages = []
21
+ osdep_packages = []
21
22
  end
22
23
 
23
24
  all_matching_osdeps = osdep_packages.map { |pkg| [pkg, true] }
@@ -232,7 +233,7 @@ def display_common_information(pkg_name, default_packages, revdeps)
232
233
  end
233
234
  end
234
235
 
235
- if !selections.empty?
236
+ unless selections.empty?
236
237
  puts " selected by way of"
237
238
  selections.each do |root_pkg|
238
239
  paths = find_selection_path(root_pkg, pkg_name)
@@ -248,9 +249,7 @@ def display_common_information(pkg_name, default_packages, revdeps)
248
249
  end
249
250
 
250
251
  def find_selection_path(from, to)
251
- if from == to
252
- return [[from]]
253
- end
252
+ return [[from]] if from == to
254
253
 
255
254
  all_paths = Array.new
256
255
  ws.manifest.resolve_package_name(from).each do |pkg_type, pkg_name|
@@ -262,19 +261,17 @@ def find_selection_path(from, to)
262
261
 
263
262
  pkg = ws.manifest.find_autobuild_package(pkg_name)
264
263
  pkg.dependencies.each do |dep_pkg_name|
265
- if result = find_selection_path(dep_pkg_name, to)
264
+ if (result = find_selection_path(dep_pkg_name, to))
266
265
  all_paths.concat(result.map { |p| path + p })
267
266
  end
268
267
  end
269
- if pkg.os_packages.include?(to)
270
- all_paths << (path + [to])
271
- end
268
+ all_paths << (path + [to]) if pkg.os_packages.include?(to)
272
269
  end
273
270
 
274
271
  # Now filter common trailing subpaths
275
272
  all_paths = all_paths.sort_by(&:size)
276
273
  filtered_paths = Array.new
277
- while !all_paths.empty?
274
+ until all_paths.empty?
278
275
  path = all_paths.shift
279
276
  filtered_paths << path
280
277
  size = path.size
@@ -290,19 +287,15 @@ def vcs_to_array(vcs)
290
287
  options = vcs.dup
291
288
  type = options.delete('type')
292
289
  url = options.delete('url')
293
- else
290
+ else
294
291
  options = vcs.options
295
292
  type = vcs.type
296
293
  url = vcs.url
297
294
  end
298
295
 
299
296
  fields = []
300
- if type
301
- fields << ['type', type]
302
- end
303
- if url
304
- fields << ['url', url]
305
- end
297
+ fields << ['type', type] if type
298
+ fields << ['url', url] if url
306
299
  fields = fields.concat(options.to_a.sort_by { |k, _| k.to_s })
307
300
  fields.map do |key, value|
308
301
  if value.respond_to?(:to_str) && File.file?(value) && value =~ /^\//
@@ -315,9 +308,10 @@ def vcs_to_array(vcs)
315
308
  def compute_all_revdeps(pkg_revdeps, revdeps)
316
309
  pkg_revdeps = pkg_revdeps.dup
317
310
  all_revdeps = Array.new
318
- while !pkg_revdeps.empty?
311
+ until pkg_revdeps.empty?
319
312
  parent_name = pkg_revdeps.shift
320
313
  next if all_revdeps.include?(parent_name)
314
+
321
315
  all_revdeps << parent_name
322
316
  pkg_revdeps.concat(revdeps[parent_name].to_a)
323
317
  end
@@ -73,7 +73,7 @@ def snapshot_overrides_vcs?(importer, vcs, snapshot)
73
73
  end
74
74
  end
75
75
 
76
- def report_exception(package_status, msg, e)
76
+ def self.report_exception(package_status, msg, e)
77
77
  package_status.msg << Autoproj.color(" #{msg} (#{e})", :red)
78
78
  if Autobuild.debug
79
79
  package_status.msg.concat(e.backtrace.map do |line|
@@ -82,8 +82,8 @@ def report_exception(package_status, msg, e)
82
82
  end
83
83
  end
84
84
 
85
- PackageStatus = Struct.new :msg, :sync, :uncommitted, :local, :remote
86
- def status_of_package(package_description, only_local: false, snapshot: false)
85
+ PackageStatus = Struct.new :msg, :sync, :unexpected, :uncommitted, :local, :remote
86
+ def self.status_of_package(package_description, only_local: false, snapshot: false)
87
87
  pkg = package_description.autobuild
88
88
  importer = pkg.importer
89
89
  package_status = PackageStatus.new(Array.new, false, false, false, false)
@@ -96,7 +96,7 @@ def status_of_package(package_description, only_local: false, snapshot: false)
96
96
  else
97
97
  begin status = importer.status(pkg, only_local: only_local)
98
98
  rescue StandardError => e
99
- report_exception(package_status, "failed to fetch status information", e)
99
+ self.report_exception(package_status, "failed to fetch status information", e)
100
100
  return package_status
101
101
  end
102
102
 
@@ -108,7 +108,7 @@ def status_of_package(package_description, only_local: false, snapshot: false)
108
108
  rescue Autobuild::PackageException
109
109
  Hash.new
110
110
  rescue StandardError => e
111
- report_exception(package_status, "failed to fetch snapshotting information", e)
111
+ self.report_exception(package_status, "failed to fetch snapshotting information", e)
112
112
  return package_status
113
113
  end
114
114
  if snapshot_overrides_vcs?(importer, package_description.vcs, snapshot_version)
@@ -122,6 +122,7 @@ def status_of_package(package_description, only_local: false, snapshot: false)
122
122
  end
123
123
 
124
124
  status.unexpected_working_copy_state.each do |msg|
125
+ package_status.unexpected = true
125
126
  package_status.msg << Autoproj.color(" #{msg}", :red, :bold)
126
127
  end
127
128
 
@@ -173,13 +174,15 @@ def each_package_status(packages, parallel: ws.config.parallel_import_level, sna
173
174
  end
174
175
  noninteractive = noninteractive.map do |pkg|
175
176
  future = Concurrent::Future.execute(executor: executor) do
176
- status_of_package(pkg, snapshot: snapshot, only_local: only_local)
177
+ Status.status_of_package(
178
+ pkg, snapshot: snapshot, only_local: only_local
179
+ )
177
180
  end
178
181
  [pkg, future]
179
182
  end
180
183
 
181
184
  (noninteractive + interactive).each do |pkg, future|
182
- if future
185
+ if future
183
186
  if progress
184
187
  wait_timeout = 1
185
188
  while true
@@ -196,7 +199,10 @@ def each_package_status(packages, parallel: ws.config.parallel_import_level, sna
196
199
  if !(status = future.value)
197
200
  raise future.reason
198
201
  end
199
- else status = status_of_package(pkg, snapshot: snapshot, only_local: only_local)
202
+ else
203
+ status = Status.status_of_package(
204
+ pkg, snapshot: snapshot, only_local: only_local
205
+ )
200
206
  end
201
207
 
202
208
  result.uncommitted ||= status.uncommitted
@@ -263,7 +269,7 @@ def display_status(packages, parallel: ws.config.parallel_import_level, snapshot
263
269
  sync_packages = ""
264
270
  end
265
271
 
266
- STDERR.print
272
+ STDERR.print
267
273
 
268
274
  if status.msg.size == 1
269
275
  Autoproj.message "#{pkg_name}: #{status.msg.first}"