autoproj 2.10.2 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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)'
@@ -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.autobuild.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
@@ -66,7 +66,7 @@ def validate_options(selection, options)
66
66
  return selection, options
67
67
  end
68
68
 
69
- def run(selected_packages, run_hook: false, **options)
69
+ def run(selected_packages, run_hook: false, report: true, **options)
70
70
  ws.manifest.accept_unavailable_osdeps = !options[:osdeps]
71
71
  ws.setup
72
72
  ws.autodetect_operating_system(force: true)
@@ -121,7 +121,8 @@ def run(selected_packages, run_hook: false, **options)
121
121
  keep_going: options[:keep_going],
122
122
  parallel: options[:parallel] || ws.config.parallel_import_level,
123
123
  retry_count: options[:retry_count],
124
- auto_exclude: options[:auto_exclude])
124
+ auto_exclude: options[:auto_exclude],
125
+ report: report)
125
126
 
126
127
  ws.finalize_setup
127
128
  ws.export_installation_manifest
@@ -195,13 +196,15 @@ def normalize_osdeps_options(
195
196
  def update_packages(selected_packages,
196
197
  from: nil, checkout_only: false, only_local: false, reset: false,
197
198
  deps: true, keep_going: false, parallel: 1,
198
- retry_count: 0, osdeps: true, auto_exclude: false, osdeps_options: Hash.new)
199
+ retry_count: 0, osdeps: true, auto_exclude: false, osdeps_options: Hash.new,
200
+ report: true)
199
201
 
200
202
  if from
201
203
  setup_update_from(from)
202
204
  end
203
205
 
204
- ops = Autoproj::Ops::Import.new(ws)
206
+ ops = Autoproj::Ops::Import.new(
207
+ ws, report_path: (ws.import_report_path if report))
205
208
  source_packages, osdep_packages =
206
209
  ops.import_packages(selected_packages,
207
210
  checkout_only: checkout_only,
@@ -0,0 +1,139 @@
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))
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
+
93
+ packages = package_names.map do |pkg_name|
94
+ ws.manifest.find_package_definition(pkg_name)
95
+ end
96
+
97
+ Autobuild.apply(
98
+ package_names,
99
+ "autoproj-#{utility_name}",
100
+ [utility_name],
101
+ parallel: options[:parallel]
102
+ )
103
+
104
+ ensure
105
+ create_report(packages) if packages && @report_path
106
+ end
107
+
108
+ def package_metadata(package)
109
+ u = package.autobuild.utility(@utility_name)
110
+ {
111
+ 'source_dir' => u.source_dir,
112
+ 'target_dir' => u.target_dir,
113
+ 'available' => !!u.available?,
114
+ 'enabled' => !!u.enabled?,
115
+ 'invoked' => !!u.invoked?,
116
+ 'success' => !!u.success?,
117
+ 'installed' => !!u.installed?,
118
+ }
119
+ end
120
+
121
+ def create_report(packages)
122
+ info = packages.each_with_object({}) do |p, map|
123
+ map[p.name] = package_metadata(p)
124
+ end
125
+
126
+ FileUtils.mkdir_p File.dirname(@report_path)
127
+ File.open(@report_path, 'w') do |io|
128
+ dump = JSON.dump(
129
+ "#{@utility_name}_report" => {
130
+ 'timestamp' => Time.now,
131
+ 'packages' => info
132
+ }
133
+ )
134
+ io.write dump
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
@@ -506,6 +506,19 @@ def utility_enabled_for?(utility, package)
506
506
  end
507
507
  end
508
508
 
509
+ # Set the given utility to enabled by default
510
+ #
511
+ # Unlike {#utility_enable_all} and {#utility_disable_all}, it does
512
+ # not touch existing exclusions
513
+ #
514
+ # @param [String] utility the utility name (e.g. 'doc' or 'test')
515
+ # @param [Boolean] enabled whether the utility will be enabled (true) or
516
+ # disabled (false)
517
+ # @return [void]
518
+ def utility_default(utility, enabled)
519
+ set("#{utility_key(utility)}_default", enabled ? true : false)
520
+ end
521
+
509
522
  # Enables a utility for all packages
510
523
  #
511
524
  # This both sets the default value for all packages and resets all
@@ -171,6 +171,13 @@ python:
171
171
  opensuse: python-devel
172
172
  default: ignore # will be installed manually by the user
173
173
 
174
+ python-setuptools:
175
+ arch: python2-distribute
176
+ debian,ubuntu: python-setuptools
177
+ fedora: python-setuptools
178
+ gentoo: dev-python/setuptools
179
+ default: ignore # will be installed manually by the user
180
+
174
181
  sudo:
175
182
  macos-brew: ignore
176
183
  default: sudo
@@ -1020,23 +1020,14 @@ def load_package_manifest(pkg)
1020
1020
  if manifest
1021
1021
  pkg.autobuild.description = manifest
1022
1022
  else
1023
- Autoproj.warn "#{package.name} from #{package_set.name} does not have a manifest"
1023
+ Autoproj.warn "#{package.name} from #{package_set.name} "\
1024
+ "does not have a manifest"
1024
1025
  end
1025
1026
 
1026
- manifest = pkg.autobuild.description
1027
- manifest.each_dependency(pkg.modes) do |name, is_optional|
1028
- begin
1029
- if is_optional
1030
- package.optional_dependency name
1031
- else
1032
- package.depends_on name
1033
- end
1034
- rescue ConfigError => e
1035
- raise ConfigError.new(manifest_path),
1036
- "manifest #{manifest_path} of #{package.name} from #{package_set.name} lists '#{name}' as dependency, but it is neither a normal package nor an osdeps package. osdeps reports: #{e.message}", e.backtrace
1037
- end
1038
- end
1039
- manifest
1027
+ pkg.apply_dependencies_from_manifest
1028
+ # #description is initialized with a null package manifest
1029
+ # return it even if we haven't overriden it
1030
+ pkg.autobuild.description
1040
1031
  end
1041
1032
 
1042
1033
  def load_all_available_package_manifests
@@ -92,35 +92,29 @@ def build_packages(all_enabled_packages, options = Hash.new)
92
92
  begin
93
93
  Autobuild.apply(all_enabled_packages, "autoproj-build", ['build'], options)
94
94
  ensure
95
- build_report(all_enabled_packages) if @report_path
95
+ create_report(all_enabled_packages) if @report_path
96
96
  end
97
97
  end
98
98
 
99
- def build_report(package_list)
99
+ def create_report(package_list)
100
100
  FileUtils.mkdir_p File.dirname(@report_path)
101
101
 
102
- packages = package_list.map do |pkg_name|
102
+ packages = package_list.each_with_object({}) do |pkg_name, h|
103
103
  pkg = manifest.find_autobuild_package(pkg_name)
104
104
 
105
- {
106
- name: pkg.name,
107
- import_invoked: pkg.import_invoked?,
108
- prepare_invoked: pkg.prepare_invoked?,
109
- build_invoked: pkg.build_invoked?,
110
- failed: pkg.failed?,
111
- imported: pkg.imported?,
112
- prepared: pkg.prepared?,
113
- built: pkg.built?
105
+ h[pkg.name] = {
106
+ invoked: !!pkg.install_invoked?,
107
+ success: !!pkg.installed?
114
108
  }
115
109
  end
116
110
 
117
- build_report = JSON.pretty_generate({
111
+ report = JSON.pretty_generate({
118
112
  build_report: {
119
113
  timestamp: Time.now,
120
114
  packages: packages
121
115
  }
122
116
  })
123
- IO.write(@report_path, build_report)
117
+ IO.write(@report_path, report)
124
118
  end
125
119
  end
126
120
  end
@@ -12,9 +12,10 @@ def auto_exclude?
12
12
  end
13
13
  attr_writer :auto_exclude
14
14
 
15
- def initialize(ws)
15
+ def initialize(ws, report_path: nil)
16
16
  @ws = ws
17
17
  @auto_exclude = false
18
+ @report_path = report_path
18
19
  end
19
20
 
20
21
  def mark_exclusion_along_revdeps(pkg_name, revdeps, chain = [], reason = nil)
@@ -22,24 +23,24 @@ def mark_exclusion_along_revdeps(pkg_name, revdeps, chain = [], reason = nil)
22
23
  chain.unshift pkg_name
23
24
  if root
24
25
  reason = ws.manifest.exclusion_reason(pkg_name)
26
+ elsif chain.size == 1
27
+ ws.manifest.exclude_package(pkg_name, "its dependency #{reason}")
25
28
  else
26
- if chain.size == 1
27
- ws.manifest.exclude_package(pkg_name, "its dependency #{reason}")
28
- else
29
- ws.manifest.exclude_package(pkg_name, "#{reason} (dependency chain: #{chain.join(">")})")
30
- end
29
+ ws.manifest.exclude_package(pkg_name, "#{reason} (dependency chain: "\
30
+ "#{chain.join('>')})")
31
31
  end
32
32
 
33
- return if !revdeps.has_key?(pkg_name)
33
+ return unless revdeps.key?(pkg_name)
34
+
34
35
  revdeps[pkg_name].each do |dep_name|
35
- if !ws.manifest.excluded?(dep_name)
36
+ unless ws.manifest.excluded?(dep_name)
36
37
  mark_exclusion_along_revdeps(dep_name, revdeps, chain.dup, reason)
37
38
  end
38
39
  end
39
40
  end
40
41
 
41
42
  VALID_OSDEP_AVAILABILITY =
42
- [OSPackageResolver::AVAILABLE, OSPackageResolver::IGNORE]
43
+ [OSPackageResolver::AVAILABLE, OSPackageResolver::IGNORE].freeze
43
44
 
44
45
  def import_next_step(pkg, reverse_dependencies)
45
46
  new_packages = []
@@ -85,23 +86,32 @@ def pre_package_import(selection, manifest, pkg, reverse_dependencies)
85
86
  elsif manifest.ignored?(pkg.name)
86
87
  false
87
88
  elsif !pkg.importer && !File.directory?(pkg.srcdir)
88
- raise ConfigError.new, "#{pkg.name} has no VCS, but is not checked out in #{pkg.srcdir}"
89
+ raise ConfigError.new, "#{pkg.name} has no VCS, but is not "\
90
+ "checked out in #{pkg.srcdir}"
89
91
  else
90
92
  true
91
93
  end
92
94
  end
93
95
 
94
- def post_package_import(selection, manifest, pkg, reverse_dependencies, auto_exclude: auto_exclude?)
95
- Rake::Task["#{pkg.name}-import"].instance_variable_set(:@already_invoked, true)
96
+ def post_package_import(selection, manifest, pkg, reverse_dependencies,
97
+ auto_exclude: auto_exclude?)
98
+ Rake::Task["#{pkg.name}-import"]
99
+ .instance_variable_set(:@already_invoked, true)
96
100
  if pkg.checked_out?
97
101
  begin
98
102
  manifest.load_package_manifest(pkg.name)
99
- rescue Exception => e
100
- raise if !auto_exclude
101
- manifest.add_exclusion(pkg.name, "#{pkg.name} failed to import with #{e} and auto_exclude was true")
103
+ rescue StandardError => e
104
+ raise unless auto_exclude
105
+
106
+ manifest.add_exclusion(pkg.name, "#{pkg.name} failed to import "\
107
+ "with #{e} and auto_exclude was true")
102
108
  end
103
109
  end
104
110
 
111
+ if !manifest.excluded?(pkg.name) && !manifest.ignored?(pkg.name)
112
+ process_post_import_blocks(pkg) if pkg.checked_out?
113
+ end
114
+
105
115
  # The package setup mechanisms might have added an exclusion
106
116
  # on this package. Handle this.
107
117
  if manifest.excluded?(pkg.name)
@@ -113,10 +123,8 @@ def post_package_import(selection, manifest, pkg, reverse_dependencies, auto_exc
113
123
  elsif manifest.ignored?(pkg.name)
114
124
  false
115
125
  else
116
- if pkg.checked_out?
117
- process_post_import_blocks(pkg)
118
- end
119
- import_next_step(pkg, reverse_dependencies)
126
+ pkg.apply_dependencies_from_manifest
127
+ import_next_step(pkg.autobuild, reverse_dependencies)
120
128
  end
121
129
  end
122
130
 
@@ -163,16 +171,16 @@ def install_internal_dependencies_for(*packages, **osdeps_options)
163
171
  # @param [Integer] retry_count the number of retries that are
164
172
  # allowed. Set to zero for no retry
165
173
  # @param [Hash] import_options options passed to {Autobuild::Importer#import}
166
- def queue_import_work(executor, completion_queue, pkg, retry_count: nil, **import_options)
167
- import_future = Concurrent::Future.new(executor: executor, args: [pkg]) do |import_pkg|
174
+ def queue_import_work(executor, completion_queue, pkg,
175
+ retry_count: nil, **import_options)
176
+ import_future = Concurrent::Future
177
+ .new(executor: executor, args: [pkg]) do |import_pkg|
168
178
  ## COMPLETELY BYPASS RAKE HERE
169
179
  # The reason is that the ordering of import/prepare between
170
180
  # packages is not important BUT the ordering of import vs.
171
181
  # prepare in one package IS important: prepare is the method
172
182
  # that takes into account dependencies.
173
- if retry_count
174
- import_pkg.autobuild.importer.retry_count = retry_count
175
- end
183
+ import_pkg.autobuild.importer.retry_count = retry_count if retry_count
176
184
  import_pkg.autobuild.import(**import_options)
177
185
  end
178
186
  import_future.add_observer do |time, result, reason|
@@ -193,8 +201,10 @@ def import_selected_packages(selection,
193
201
  auto_exclude: auto_exclude?,
194
202
  **import_options)
195
203
 
196
- if ![:checkout, :ignore, :return].include?(non_imported_packages)
197
- raise ArgumentError, "invalid value for 'non_imported_packages'. Expected one of :checkout, :ignore or :return but got #{non_imported_packages}"
204
+ unless %i[checkout ignore return].include?(non_imported_packages)
205
+ raise ArgumentError, "invalid value for 'non_imported_packages'. "\
206
+ "Expected one of :checkout, :ignore or :return "\
207
+ "but got #{non_imported_packages}"
198
208
  end
199
209
 
200
210
  # This is used in the ensure block, initialize as early as
@@ -220,6 +230,7 @@ def import_selected_packages(selection,
220
230
  all_processed_packages = Set.new
221
231
  main_thread_imports = Array.new
222
232
  package_queue = selected_packages.to_a.sort_by(&:name)
233
+
223
234
  failures = Array.new
224
235
  missing_vcs = Array.new
225
236
  installed_vcs_packages = Set['none', 'local']
@@ -228,24 +239,25 @@ def import_selected_packages(selection,
228
239
  package_queue.each do |pkg|
229
240
  # Remove packages that have already been processed
230
241
  next if all_processed_packages.include?(pkg)
231
- if (non_imported_packages != :checkout) && !File.directory?(pkg.autobuild.srcdir)
242
+
243
+ vcs_installed = installed_vcs_packages.include?(pkg.vcs.type)
244
+ if (non_imported_packages != :checkout) && !pkg.checked_out?
245
+ all_processed_packages << pkg
232
246
  if non_imported_packages == :return
233
- all_processed_packages << pkg
234
247
  completion_queue << [pkg, Time.now, false, nil]
235
- next
236
248
  else
237
- all_processed_packages << pkg
238
249
  ws.manifest.ignore_package(pkg.name)
239
- next
240
250
  end
241
- elsif install_vcs_packages && !installed_vcs_packages.include?(pkg.vcs.type)
251
+ next
252
+ elsif install_vcs_packages && !vcs_installed
242
253
  missing_vcs << pkg
243
254
  next
244
255
  end
245
256
  all_processed_packages << pkg
246
257
 
247
258
  importer = pkg.autobuild.importer
248
- if !pre_package_import(selection, manifest, pkg.autobuild, reverse_dependencies)
259
+ if !pre_package_import(selection, manifest, pkg.autobuild,
260
+ reverse_dependencies)
249
261
  next
250
262
  elsif !importer
251
263
  # The validity of this is checked in
@@ -255,7 +267,7 @@ def import_selected_packages(selection,
255
267
  elsif importer.interactive?
256
268
  main_thread_imports << pkg
257
269
  next
258
- elsif pkg.autobuild.checked_out? && import_options[:checkout_only]
270
+ elsif pkg.checked_out? && import_options[:checkout_only]
259
271
  main_thread_imports << pkg
260
272
  next
261
273
  end
@@ -263,20 +275,21 @@ def import_selected_packages(selection,
263
275
  pending_packages << pkg
264
276
  begin
265
277
  queue_import_work(
266
- executor, completion_queue, pkg, retry_count: retry_count,
278
+ executor, completion_queue, pkg,
279
+ retry_count: retry_count,
267
280
  **import_options.merge(allow_interactive: false))
268
281
  rescue Exception
269
282
  pending_packages.delete(pkg)
270
283
  raise
271
284
  end
272
- true
273
285
  end
274
286
  package_queue.clear
275
287
 
276
288
  if completion_queue.empty? && pending_packages.empty?
277
- if !missing_vcs.empty?
289
+ unless missing_vcs.empty?
278
290
  installed_vcs_packages.merge(
279
- install_vcs_packages_for(*missing_vcs, **install_vcs_packages))
291
+ install_vcs_packages_for(*missing_vcs,
292
+ **install_vcs_packages))
280
293
  package_queue.concat(missing_vcs)
281
294
  missing_vcs.clear
282
295
  next
@@ -289,15 +302,17 @@ def import_selected_packages(selection,
289
302
  break
290
303
  else
291
304
  main_thread_imports.delete_if do |pkg|
305
+ # rubocop:disable Lint/HandleExceptions
292
306
  begin
293
307
  if retry_count
294
308
  pkg.autobuild.importer.retry_count = retry_count
295
309
  end
296
310
  result = pkg.autobuild.import(
297
311
  **import_options.merge(allow_interactive: true))
298
- rescue Exception => reason
312
+ rescue StandardError => e
299
313
  end
300
- completion_queue << [pkg, Time.now, result, reason]
314
+ completion_queue << [pkg, Time.now, result, e]
315
+ # rubocop:enable Lint/HandleExceptions
301
316
  end
302
317
  end
303
318
  end
@@ -309,20 +324,21 @@ def import_selected_packages(selection,
309
324
  if reason.kind_of?(Autobuild::InteractionRequired)
310
325
  main_thread_imports << pkg
311
326
  elsif auto_exclude
312
- manifest.add_exclusion(pkg.name, "#{pkg.name} failed to import with #{reason} and auto_exclude was true")
327
+ manifest.add_exclusion(
328
+ pkg.name, "#{pkg.name} failed to import with "\
329
+ "#{reason} and auto_exclude was true")
313
330
  selection.filter_excluded_and_ignored_packages(manifest)
314
331
  else
315
332
  # One importer failed... terminate
316
333
  Autoproj.error "import of #{pkg.name} failed"
317
- if !reason.kind_of?(Interrupt)
318
- Autoproj.error "#{reason}"
319
- end
334
+ Autoproj.error reason.to_s unless reason.kind_of?(Interrupt)
320
335
  failures << reason
321
336
  end
322
337
  else
323
- if new_packages = post_package_import(
324
- selection, manifest, pkg.autobuild, reverse_dependencies,
325
- auto_exclude: auto_exclude)
338
+ new_packages = post_package_import(
339
+ selection, manifest, pkg, reverse_dependencies,
340
+ auto_exclude: auto_exclude)
341
+ if new_packages
326
342
  # Excluded dependencies might have caused the package to be
327
343
  # excluded as well ... do not add any dependency to the
328
344
  # processing queue if it is the case
@@ -336,10 +352,10 @@ def import_selected_packages(selection,
336
352
  end
337
353
 
338
354
  all_processed_packages.delete_if do |processed_pkg|
339
- ws.manifest.excluded?(processed_pkg.name) || ws.manifest.ignored?(processed_pkg.name)
355
+ ws.manifest.excluded?(processed_pkg.name) ||
356
+ ws.manifest.ignored?(processed_pkg.name)
340
357
  end
341
- return all_processed_packages, failures
342
-
358
+ [all_processed_packages, failures]
343
359
  ensure
344
360
  if failures && !failures.empty? && !keep_going
345
361
  Autoproj.error "waiting for pending import jobs to finish"
@@ -354,13 +370,16 @@ def finalize_package_load(processed_packages, auto_exclude: auto_exclude?)
354
370
  manifest = ws.manifest
355
371
 
356
372
  all = Set.new
357
- package_queue = manifest.all_layout_packages(false).each_source_package_name.to_a +
373
+ package_queue =
374
+ manifest.all_layout_packages(false)
375
+ .each_source_package_name.to_a +
358
376
  processed_packages.map(&:name).to_a
359
- while !package_queue.empty?
377
+
378
+ until package_queue.empty?
360
379
  pkg_name = package_queue.shift
361
380
  next if all.include?(pkg_name)
362
- all << pkg_name
363
381
 
382
+ all << pkg_name
364
383
  next if manifest.ignored?(pkg_name) || manifest.excluded?(pkg_name)
365
384
 
366
385
  pkg_definition = manifest.find_package_definition(pkg_name)
@@ -370,27 +389,28 @@ def finalize_package_load(processed_packages, auto_exclude: auto_exclude?)
370
389
  manifest.load_package_manifest(pkg.name)
371
390
  process_post_import_blocks(pkg)
372
391
  rescue Exception => e
373
- raise if !auto_exclude
374
- manifest.exclude_package(pkg.name, "#{pkg.name} had an error when being loaded (#{e.message}) and auto_exclude is true")
392
+ raise unless auto_exclude
393
+
394
+ manifest.exclude_package(
395
+ pkg.name, "#{pkg.name} had an error when "\
396
+ "being loaded (#{e.message}) and "\
397
+ "auto_exclude is true")
375
398
  next
376
399
  end
377
400
  end
378
401
 
379
402
  packages, osdeps = pkg.partition_optional_dependencies
380
- packages.each do |dep_pkg_name|
381
- if !manifest.ignored?(dep_pkg_name) && !manifest.excluded?(dep_pkg_name)
382
- pkg.depends_on dep_pkg_name
383
- end
384
- end
385
- osdeps.each do |osdep_pkg_name|
386
- if !manifest.ignored?(osdep_pkg_name) && !manifest.excluded?(osdep_pkg_name)
387
- pkg.os_packages << osdep_pkg_name
388
- end
403
+ (packages + osdeps).each do |dep_pkg_name|
404
+ next if manifest.ignored?(dep_pkg_name)
405
+ next if manifest.excluded?(dep_pkg_name)
406
+
407
+ pkg.depends_on dep_pkg_name
389
408
  end
390
409
 
391
410
  if File.directory?(pkg.srcdir)
392
411
  pkg.prepare
393
- Rake::Task["#{pkg.name}-prepare"].instance_variable_set(:@already_invoked, true)
412
+ Rake::Task["#{pkg.name}-prepare"]
413
+ .instance_variable_set(:@already_invoked, true)
394
414
  end
395
415
  pkg.update_environment
396
416
  package_queue.concat(pkg.dependencies)
@@ -419,9 +439,7 @@ def import_packages(selection,
419
439
  auto_exclude: auto_exclude,
420
440
  **import_options)
421
441
 
422
- if !keep_going && !failures.empty?
423
- raise failures.first
424
- end
442
+ raise failures.first if !keep_going && !failures.empty?
425
443
 
426
444
  install_internal_dependencies_for(*all_processed_packages)
427
445
  finalize_package_load(all_processed_packages, auto_exclude: auto_exclude)
@@ -437,14 +455,17 @@ def import_packages(selection,
437
455
  if warn_about_excluded_packages
438
456
  selection.exclusions.each do |sel, pkg_names|
439
457
  pkg_names.sort.each do |pkg_name|
440
- Autoproj.warn "#{pkg_name}, which was selected for #{sel}, cannot be built: #{manifest.exclusion_reason(pkg_name)}", :bold
458
+ Autoproj.warn "#{pkg_name}, which was selected "\
459
+ "for #{sel}, cannot be built: "\
460
+ "#{manifest.exclusion_reason(pkg_name)}", :bold
441
461
  end
442
462
  end
443
463
  end
444
464
  if warn_about_ignored_packages
445
465
  selection.ignores.each do |sel, pkg_names|
446
466
  pkg_names.sort.each do |pkg_name|
447
- Autoproj.warn "#{pkg_name}, which was selected for #{sel}, is ignored", :bold
467
+ Autoproj.warn "#{pkg_name}, which was selected for #{sel}, "\
468
+ "is ignored", :bold
448
469
  end
449
470
  end
450
471
  end
@@ -452,41 +473,67 @@ def import_packages(selection,
452
473
  if !failures.empty?
453
474
  raise PackageImportFailed.new(
454
475
  failures, source_packages: all_enabled_sources,
455
- osdep_packages: all_enabled_osdeps)
476
+ osdep_packages: all_enabled_osdeps)
456
477
  else
457
478
  return all_enabled_sources, all_enabled_osdeps
458
479
  end
459
-
460
480
  ensure
461
- if ws.config.import_log_enabled? && Autoproj::Ops::Snapshot.update_log_available?(manifest)
462
- update_log_for_processed_packages(all_processed_packages || Array.new, $!)
481
+ create_report(all_processed_packages || []) if @report_path
482
+
483
+ update_log = ws.config.import_log_enabled? &&
484
+ Autoproj::Ops::Snapshot.update_log_available?(manifest)
485
+ if update_log
486
+ update_log_for_processed_packages(
487
+ all_processed_packages || Array.new, $!)
463
488
  end
464
489
  end
465
490
 
491
+ # Call post-import blcoks registered for the given package
492
+ #
493
+ # @param [PackageDefinition] pkg
466
494
  def process_post_import_blocks(pkg)
467
495
  Autoproj.each_post_import_block(pkg) do |block|
468
496
  block.call(pkg)
469
497
  end
470
498
  end
471
499
 
500
+ def create_report(package_list)
501
+ FileUtils.mkdir_p File.dirname(@report_path)
502
+
503
+ packages = package_list.each_with_object({}) do |pkg_name, h|
504
+ pkg = @ws.manifest.find_autobuild_package(pkg_name)
505
+
506
+ h[pkg.name] = {
507
+ invoked: !!pkg.import_invoked?,
508
+ success: !!pkg.imported?
509
+ }
510
+ end
511
+
512
+ report = JSON.pretty_generate({
513
+ import_report: {
514
+ timestamp: Time.now,
515
+ packages: packages
516
+ }
517
+ })
518
+ IO.write(@report_path, report)
519
+ end
520
+
472
521
  def update_log_for_processed_packages(all_processed_packages, exception)
473
522
  all_updated_packages = all_processed_packages.find_all do |processed_pkg|
474
523
  processed_pkg.autobuild.updated?
475
524
  end
476
525
 
477
- if !all_updated_packages.empty?
526
+ unless all_updated_packages.empty?
478
527
  failure_message =
479
528
  if exception
480
529
  " (#{exception.message.split("\n").first})"
481
530
  end
482
531
  ops = Ops::Snapshot.new(ws.manifest, keep_going: true)
483
532
  ops.update_package_import_state(
484
- "#{$0} #{ARGV.join(" ")}#{failure_message}",
533
+ "#{$0} #{ARGV.join(' ')}#{failure_message}",
485
534
  all_updated_packages.map(&:name))
486
535
  end
487
536
  end
488
537
  end
489
538
  end
490
539
  end
491
-
492
-