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,92 +1,21 @@
1
- require 'autoproj/cli/inspection_tool'
1
+ require 'autoproj/cli/utility'
2
2
 
3
3
  module Autoproj
4
4
  module CLI
5
- class Test < InspectionTool
6
- def enable(user_selection, options = {})
7
- if user_selection.empty?
8
- ws.load_config
9
- ws.config.utility_enable_all('test')
10
- else
11
- initialize_and_load
12
- selection, = finalize_setup(
13
- user_selection,
14
- recursive: options[:deps],
15
- non_imported_packages: :return
16
- )
17
- ws.config.utility_enable('test', *selection)
18
- end
19
- ws.config.save
5
+ class Test < Utility
6
+ def initialize(ws = Workspace.default,
7
+ name: 'test',
8
+ report_path: ws.utility_report_path('test'))
9
+ super
20
10
  end
21
11
 
22
- def disable(user_selection, options = {})
23
- if user_selection.empty?
24
- ws.load_config
25
- ws.config.utility_disable_all('test')
26
- else
27
- initialize_and_load
28
- selection, = finalize_setup(
29
- user_selection,
30
- recursive: options[:deps],
31
- non_imported_packages: :return
32
- )
33
- ws.config.utility_disable('test', *selection)
34
- end
35
- ws.config.save
36
- end
37
-
38
- def list(user_selection, options = {})
39
- initialize_and_load
40
- resolved_selection, = finalize_setup(
41
- user_selection,
42
- recursive: options[:deps],
43
- non_imported_packages: :return
44
- )
45
-
46
- lines = []
47
- resolved_selection.each do |pkg_name|
48
- pkg = ws.manifest.find_package_definition(pkg_name).autobuild
49
- lines << [
50
- pkg.name,
51
- pkg.test_utility.enabled?,
52
- pkg.test_utility.available?
53
- ]
54
- end
55
- lines = lines.sort_by { |name, _| name }
56
- w = lines.map { |name, _| name.length }.max
57
- out_format = "%-#{w}s %-7s %-9s"
58
- puts format(out_format, 'Package Name', 'Enabled', 'Available')
59
- lines.each do |name, enabled, available|
60
- puts(format(out_format, name, (!!enabled).to_s, (!!available).to_s))
61
- end
62
- end
63
-
64
- def run(user_selection, options = {})
65
- options[:parallel] ||= ws.config.parallel_build_level
66
- initialize_and_load
67
-
68
- packages, _, resolved_selection = finalize_setup(
69
- user_selection,
70
- recursive: user_selection.empty? || options[:deps]
71
- )
72
-
73
- validate_user_selection(user_selection, resolved_selection)
74
- if packages.empty?
75
- raise CLIInvalidArguments, "autoproj: the provided package "\
76
- "is not selected for build"
77
- end
78
-
79
- packages.each do |pkg|
80
- ws.manifest.find_autobuild_package(pkg).disable_phases(
81
- 'import', 'prepare', 'install'
82
- )
83
- end
84
-
85
- Autobuild.apply(
86
- packages,
87
- 'autoproj-test',
88
- ['test'],
89
- parallel: options[:parallel]
12
+ def package_metadata(package)
13
+ u = package.test_utility
14
+ super.merge(
15
+ 'coverage_available' => !!u.coverage_available?,
16
+ 'coverage_enabled' => !!u.coverage_enabled?,
17
+ 'coverage_source_dir' => u.coverage_source_dir,
18
+ 'coverage_target_dir' => u.coverage_target_dir
90
19
  )
91
20
  end
92
21
  end
@@ -1,5 +1,6 @@
1
1
  require 'autoproj/cli'
2
2
  require 'autoproj/cli/base'
3
+ require 'autoproj/cli/status'
3
4
  require 'autoproj/ops/import'
4
5
 
5
6
  module Autoproj
@@ -66,17 +67,20 @@ def validate_options(selection, options)
66
67
  return selection, options
67
68
  end
68
69
 
69
- def run(selected_packages, run_hook: false, **options)
70
+ def run(selected_packages, run_hook: false, report: true, ask: false, **options)
70
71
  ws.manifest.accept_unavailable_osdeps = !options[:osdeps]
71
72
  ws.setup
72
73
  ws.autodetect_operating_system(force: true)
73
- if options[:bundler]
74
- ws.update_bundler
75
- end
76
- if options[:autoproj]
77
- ws.update_autoproj
74
+
75
+ if ask
76
+ prompt = TTY::Prompt.new
77
+ options[:bundler] &&= prompt.yes?("Update bundler ?")
78
+ options[:autoproj] &&= prompt.yes?("Update autoproj ?")
78
79
  end
79
80
 
81
+ ws.update_bundler if options[:bundler]
82
+ ws.update_autoproj if options[:autoproj]
83
+
80
84
  begin
81
85
  ws.load_package_sets(
82
86
  mainline: options[:mainline],
@@ -84,7 +88,8 @@ def run(selected_packages, run_hook: false, **options)
84
88
  checkout_only: !options[:config] || options[:checkout_only],
85
89
  reset: options[:reset],
86
90
  keep_going: options[:keep_going],
87
- retry_count: options[:retry_count])
91
+ retry_count: options[:retry_count]
92
+ )
88
93
  rescue ImportFailed => configuration_import_failure
89
94
  if !options[:keep_going]
90
95
  raise
@@ -121,7 +126,9 @@ def run(selected_packages, run_hook: false, **options)
121
126
  keep_going: options[:keep_going],
122
127
  parallel: options[:parallel] || ws.config.parallel_import_level,
123
128
  retry_count: options[:retry_count],
124
- auto_exclude: options[:auto_exclude])
129
+ auto_exclude: options[:auto_exclude],
130
+ ask: ask,
131
+ report: report)
125
132
 
126
133
  ws.finalize_setup
127
134
  ws.export_installation_manifest
@@ -192,16 +199,65 @@ def normalize_osdeps_options(
192
199
  osdeps_options
193
200
  end
194
201
 
202
+ class AskUpdateFilter
203
+ def initialize(prompt, parallel: 1, only_local: false)
204
+ @prompt = prompt
205
+ @only_local = only_local
206
+ @executor = Concurrent::FixedThreadPool.new(parallel, max_length: 0)
207
+
208
+ @parallel = parallel
209
+ @futures = {}
210
+ @lookahead_queue = []
211
+ end
212
+
213
+ def call(pkg)
214
+ unless (status = @futures.delete(pkg).value)
215
+ raise v.reason
216
+ end
217
+
218
+ clean = !status.unexpected &&
219
+ (status.sync || (status.local && !status.remote))
220
+ if clean
221
+ msg = Autobuild.color('already up-to-date', :green)
222
+ pkg.autobuild.message "#{msg} %s"
223
+ return false
224
+ end
225
+
226
+ Autobuild.progress_display_synchronize do
227
+ status.msg.each { |m| puts m }
228
+ @prompt.yes?("Update #{pkg.name} ?")
229
+ end
230
+ end
231
+
232
+ def lookahead(pkg)
233
+ @futures[pkg] = Concurrent::Future.execute(executor: @executor) do
234
+ Status.status_of_package(
235
+ pkg, snapshot: false, only_local: @only_local
236
+ )
237
+ end
238
+ end
239
+ end
240
+
195
241
  def update_packages(selected_packages,
196
242
  from: nil, checkout_only: false, only_local: false, reset: false,
197
243
  deps: true, keep_going: false, parallel: 1,
198
- retry_count: 0, osdeps: true, auto_exclude: false, osdeps_options: Hash.new)
244
+ retry_count: 0, osdeps: true, auto_exclude: false, osdeps_options: Hash.new,
245
+ report: true, ask: false)
199
246
 
200
- if from
201
- setup_update_from(from)
202
- end
247
+ setup_update_from(from) if from
248
+
249
+ filter =
250
+ if ask
251
+ prompt = TTY::Prompt.new
252
+ filter = AskUpdateFilter.new(
253
+ prompt, parallel: parallel, only_local: only_local
254
+ )
255
+ else
256
+ ->(pkg) { true }
257
+ end
203
258
 
204
- ops = Autoproj::Ops::Import.new(ws)
259
+ ops = Autoproj::Ops::Import.new(
260
+ ws, report_path: (ws.import_report_path if report))
205
261
  source_packages, osdep_packages =
206
262
  ops.import_packages(selected_packages,
207
263
  checkout_only: checkout_only,
@@ -212,15 +268,17 @@ def update_packages(selected_packages,
212
268
  parallel: parallel,
213
269
  retry_count: retry_count,
214
270
  install_vcs_packages: (osdeps_options if osdeps),
215
- auto_exclude: auto_exclude)
216
- return source_packages, osdep_packages, nil
271
+ auto_exclude: auto_exclude,
272
+ filter: filter)
273
+ [source_packages, osdep_packages, nil]
217
274
  rescue ExcludedSelection => e
218
275
  raise CLIInvalidSelection, e.message, e.backtrace
219
276
  rescue PackageImportFailed => import_failure
220
- if !keep_going
221
- raise
222
- end
223
- return import_failure.source_packages, import_failure.osdep_packages, import_failure
277
+ raise unless keep_going
278
+
279
+ [import_failure.source_packages,
280
+ import_failure.osdep_packages,
281
+ import_failure]
224
282
  end
225
283
 
226
284
  def setup_update_from(other_root)
@@ -0,0 +1,136 @@
1
+ require 'autoproj/cli/inspection_tool'
2
+
3
+ module Autoproj
4
+ module CLI
5
+ class Utility < InspectionTool
6
+ def initialize(ws, name: nil, report_path: nil)
7
+ @utility_name = name
8
+ @report_path = report_path
9
+ super(ws)
10
+ end
11
+
12
+ attr_reader :utility_name
13
+ def default(enabled)
14
+ ws.load_config
15
+ ws.config.utility_default(utility_name, enabled)
16
+ ws.config.save
17
+ end
18
+
19
+ def enable(user_selection, options = {})
20
+ if user_selection.empty?
21
+ ws.load_config
22
+ ws.config.utility_enable_all(utility_name)
23
+ else
24
+ initialize_and_load
25
+ selection, = finalize_setup(
26
+ user_selection,
27
+ recursive: options[:deps],
28
+ non_imported_packages: :return
29
+ )
30
+ ws.config.utility_enable(utility_name, *selection)
31
+ end
32
+ ws.config.save
33
+ end
34
+
35
+ def disable(user_selection, options = {})
36
+ if user_selection.empty?
37
+ ws.load_config
38
+ ws.config.utility_disable_all(utility_name)
39
+ else
40
+ initialize_and_load
41
+ selection, = finalize_setup(
42
+ user_selection,
43
+ recursive: options[:deps],
44
+ non_imported_packages: :return
45
+ )
46
+ ws.config.utility_disable(utility_name, *selection)
47
+ end
48
+ ws.config.save
49
+ end
50
+
51
+ def list(user_selection, options = {})
52
+ initialize_and_load
53
+ resolved_selection, = finalize_setup(
54
+ user_selection,
55
+ recursive: options[:deps],
56
+ non_imported_packages: :return
57
+ )
58
+
59
+ lines = []
60
+ resolved_selection.each do |pkg_name|
61
+ pkg = ws.manifest.find_package_definition(pkg_name).autobuild
62
+ lines << [
63
+ pkg.name,
64
+ pkg.send("#{utility_name}_utility").enabled?,
65
+ pkg.send("#{utility_name}_utility").available?
66
+ ]
67
+ end
68
+ lines = lines.sort_by { |name, _| name }
69
+ w = lines.map { |name, _| name.length }.max
70
+ out_format = "%-#{w}s %-7s %-9s"
71
+ puts format(out_format, 'Package Name', 'Enabled', 'Available')
72
+ lines.each do |name, enabled, available|
73
+ puts(format(out_format, name, (!!enabled).to_s, (!!available).to_s)) # rubocop:disable Style/DoubleNegation
74
+ end
75
+ end
76
+
77
+ def run(user_selection, options = {})
78
+ options[:parallel] ||= ws.config.parallel_build_level
79
+ initialize_and_load
80
+
81
+ user_selection, = normalize_command_line_package_selection(user_selection)
82
+ package_names, _, resolved_selection = finalize_setup(
83
+ user_selection,
84
+ recursive: user_selection.empty? || options[:deps]
85
+ )
86
+
87
+ validate_user_selection(user_selection, resolved_selection)
88
+ if package_names.empty?
89
+ raise CLIInvalidArguments, "autoproj: the provided package "\
90
+ "is not selected for build"
91
+ end
92
+ return if package_names.empty?
93
+
94
+ packages = package_names.map do |pkg_name|
95
+ ws.manifest.find_package_definition(pkg_name)
96
+ end
97
+
98
+ apply_to_packages(packages, parallel: options[:parallel])
99
+ end
100
+
101
+ def apply_to_packages(packages, parallel: ws.config.parallel_build_level)
102
+ if @report_path
103
+ reporting = Ops::PhaseReporting.new(
104
+ @utility_name, @report_path,
105
+ method(:package_metadata)
106
+ )
107
+ end
108
+
109
+ reporting&.initialize_incremental_report
110
+ Autobuild.apply(
111
+ packages.map(&:name), "autoproj-#{@utility_name}",
112
+ [@utility_name], parallel: parallel
113
+ ) do |pkg, phase|
114
+ reporting&.report_incremental(pkg) if phase == utility_name
115
+ end
116
+ ensure
117
+ reporting&.create_report(packages.map(&:autobuild))
118
+ end
119
+
120
+ def package_metadata(autobuild_package)
121
+ # rubocop:disable Style/DoubleNegation
122
+ u = autobuild_package.utility(@utility_name)
123
+ {
124
+ 'source_dir' => u.source_dir,
125
+ 'target_dir' => u.target_dir,
126
+ 'available' => !!u.available?,
127
+ 'enabled' => !!u.enabled?,
128
+ 'invoked' => !!u.invoked?,
129
+ 'success' => !!u.success?,
130
+ 'installed' => !!u.installed?
131
+ }
132
+ # rubocop:enable Style/DoubleNegation
133
+ end
134
+ end
135
+ end
136
+ end
@@ -196,7 +196,9 @@ def configure(option_name)
196
196
  Autoproj.info " using: #{value} (noninteractive mode)"
197
197
  end
198
198
  @modified = true
199
- if !is_default
199
+ if is_default
200
+ value = opt.validate(value)
201
+ else
200
202
  config[option_name] = [value, true]
201
203
  displayed_options[option_name] = value
202
204
  end
@@ -242,10 +244,10 @@ def save(path = self.path, force: false)
242
244
  @modified = false
243
245
  end
244
246
 
245
- def each_reused_autoproj_installation
247
+ def each_reused_autoproj_installation(&block)
246
248
  if has_value_for?('reused_autoproj_installations')
247
- get('reused_autoproj_installations').each(&proc)
248
- else [].each(&proc)
249
+ get('reused_autoproj_installations').each(&block)
250
+ else [].each(&block)
249
251
  end
250
252
  end
251
253
 
@@ -353,6 +355,10 @@ def shell_helpers=(flag)
353
355
  set 'shell_helpers', flag, true
354
356
  end
355
357
 
358
+ def bundler_version
359
+ get 'bundler_version', nil
360
+ end
361
+
356
362
  def apply_autobuild_configuration
357
363
  if has_value_for?('autobuild')
358
364
  params = get('autobuild')
@@ -369,6 +375,11 @@ def importer_cache_dir
369
375
  get('importer_cache_dir', nil)
370
376
  end
371
377
 
378
+ # Set import and gem cache directory
379
+ def importer_cache_dir=(path)
380
+ set('importer_cache_dir', path, true)
381
+ end
382
+
372
383
  # Sets the directory in which packages will be installed
373
384
  def prefix_dir=(path)
374
385
  set('prefix', path, true)
@@ -506,6 +517,19 @@ def utility_enabled_for?(utility, package)
506
517
  end
507
518
  end
508
519
 
520
+ # Set the given utility to enabled by default
521
+ #
522
+ # Unlike {#utility_enable_all} and {#utility_disable_all}, it does
523
+ # not touch existing exclusions
524
+ #
525
+ # @param [String] utility the utility name (e.g. 'doc' or 'test')
526
+ # @param [Boolean] enabled whether the utility will be enabled (true) or
527
+ # disabled (false)
528
+ # @return [void]
529
+ def utility_default(utility, enabled)
530
+ set("#{utility_key(utility)}_default", enabled ? true : false)
531
+ end
532
+
509
533
  # Enables a utility for all packages
510
534
  #
511
535
  # This both sets the default value for all packages and resets all