autoproj 1.12.6 → 1.13.0.b1

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.
@@ -0,0 +1,94 @@
1
+ require 'autoproj'
2
+ require 'autoproj/cmdline'
3
+ require 'autoproj/ops/tools'
4
+ require 'autoproj/ops/snapshot'
5
+
6
+ module Autoproj
7
+ module CLI
8
+ class Versions
9
+ include Ops::Tools
10
+
11
+ DEFAULT_VERSIONS_FILE_BASENAME = Ops::Snapshot::DEFAULT_VERSIONS_FILE_BASENAME
12
+
13
+ def default_versions_file
14
+ File.join( Autoproj.overrides_dir, DEFAULT_VERSIONS_FILE_BASENAME )
15
+ end
16
+
17
+ attr_reader :manifest
18
+
19
+ def initialize(manifest)
20
+ @manifest = manifest
21
+ end
22
+
23
+ def resolve_selection( user_selection )
24
+ resolved_selection = CmdLine.
25
+ resolve_user_selection(user_selection, :filter => false)
26
+ resolved_selection.filter_excluded_and_ignored_packages(manifest)
27
+ # This calls #prepare, which is required to run build_packages
28
+ packages = CmdLine.import_packages(resolved_selection)
29
+
30
+ # Remove non-existing packages
31
+ packages.each do |pkg|
32
+ if !File.directory?(manifest.package(pkg).autobuild.srcdir)
33
+ raise ConfigError, "cannot commit #{pkg} as it is not checked out"
34
+ end
35
+ end
36
+ packages
37
+ end
38
+
39
+
40
+ def parse_options(args)
41
+ options = Hash.new
42
+ parser = OptionParser.new do |opt|
43
+ opt.on '--[no-]package-sets', 'commit the package set state as well (default if no packages are selected)' do |flag|
44
+ options[:package_sets] = flag
45
+ end
46
+ opt.on '--replace', String, 'if the file given to --save exists, replace it instead of updating it' do
47
+ options[:replace] = true
48
+ end
49
+ opt.on '-k', '--keep-going', "ignore packages that can't be snapshotted (the default is to terminate with an error)" do
50
+ options[:keep_going] = true
51
+ end
52
+ opt.on '--save[=FILE]', String, "the file into which the versions should be saved (if no file is given, defaults to #{default_versions_file})" do |file|
53
+ options[:output_file] =
54
+ if file == '-'
55
+ nil
56
+ elsif !file
57
+ default_versions_file
58
+ else
59
+ file
60
+ end
61
+ end
62
+ end
63
+ common_options(parser)
64
+ remaining = parser.parse(args)
65
+ return remaining, options
66
+ end
67
+
68
+ def run(user_selection, options)
69
+ do_package_sets = options[:package_sets]
70
+ if do_package_sets.nil? && user_selection.empty?
71
+ do_package_sets = true
72
+ end
73
+
74
+ CmdLine.report(silent: true) do
75
+ packages = resolve_selection user_selection
76
+ ops = Ops::Snapshot.new(manifest, keep_going: options[:keep_going])
77
+
78
+ versions = Array.new
79
+ if do_package_sets
80
+ versions += ops.snapshot_package_sets
81
+ end
82
+ versions += ops.snapshot_packages(packages)
83
+ if output_file = options[:output_file]
84
+ ops.save_versions(versions, output_file, replace: options[:replace])
85
+ else
86
+ versions = ops.sort_versions(versions)
87
+ puts YAML.dump(versions)
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+
@@ -43,6 +43,14 @@ module Autoproj
43
43
  end
44
44
 
45
45
  module CmdLine
46
+ def self.argv
47
+ if defined? ORIGINAL_ARGV
48
+ ORIGINAL_ARGV
49
+ else
50
+ ARGV
51
+ end
52
+ end
53
+
46
54
  def self.config
47
55
  Autoproj.config
48
56
  end
@@ -193,17 +201,11 @@ module Autoproj
193
201
  Autoproj.save_config
194
202
  ENV['AUTOPROJ_RESTARTING'] = '1'
195
203
  require 'rbconfig'
196
- if defined?(ORIGINAL_ARGV)
197
- exec(ruby_executable, $0, *ORIGINAL_ARGV)
198
- else
199
- exec(ruby_executable, $0, *ARGV)
200
- end
204
+ exec(ruby_executable, $0, *argv)
201
205
  end
202
206
  end
203
207
 
204
208
  def self.load_configuration(silent = false)
205
- manifest = Autoproj.manifest
206
-
207
209
  manifest.each_package_set do |pkg_set|
208
210
  if Gem::Version.new(pkg_set.required_autoproj_version) > Gem::Version.new(Autoproj::VERSION)
209
211
  raise ConfigError.new(pkg_set.source_file), "the #{pkg_set.name} package set requires autoproj v#{pkg_set.required_autoproj_version} but this is v#{Autoproj::VERSION}"
@@ -254,6 +256,13 @@ module Autoproj
254
256
  end
255
257
  end
256
258
 
259
+ manifest.each_autobuild_package do |pkg|
260
+ Autobuild.each_utility do |uname, _|
261
+ pkg.utility(uname).enabled =
262
+ config.utility_enabled_for?(uname, pkg.name)
263
+ end
264
+ end
265
+
257
266
  # We finished loading the configuration files. Not all configuration
258
267
  # is done (since we need to process the package setup blocks), but
259
268
  # save the current state of the configuration anyway.
@@ -261,7 +270,7 @@ module Autoproj
261
270
  end
262
271
 
263
272
  def self.update_configuration
264
- Ops::Configuration.new(Autoproj.manifest, Ops.loader).update_configuration(only_local?)
273
+ Ops::Configuration.new(manifest, Ops.loader).update_configuration(only_local?)
265
274
  end
266
275
 
267
276
  def self.setup_package_directories(pkg)
@@ -289,11 +298,9 @@ module Autoproj
289
298
 
290
299
 
291
300
  def self.setup_all_package_directories
292
- manifest = Autoproj.manifest
293
-
294
301
  # Override the package directories from our reused installations
295
302
  imported_packages = Set.new
296
- Autoproj.manifest.reused_installations.each do |imported_manifest|
303
+ manifest.reused_installations.each do |imported_manifest|
297
304
  imported_manifest.each do |imported_pkg|
298
305
  imported_packages << imported_pkg.name
299
306
  if pkg = manifest.find_package(imported_pkg.name)
@@ -365,9 +372,13 @@ module Autoproj
365
372
  end
366
373
 
367
374
  def self.update_environment
368
- Autoproj.manifest.reused_installations.each do |manifest|
369
- manifest.each do |pkg|
370
- Autobuild::Package[pkg.name].update_environment
375
+ manifest.reused_installations.each do |reused_manifest|
376
+ reused_manifest.each do |pkg|
377
+ # The reused installations might have packages we do not
378
+ # know about, just ignore them
379
+ if pkg = manifest.find_autobuild_package(pkg)
380
+ pkg.update_environment
381
+ end
371
382
  end
372
383
  end
373
384
 
@@ -526,8 +537,6 @@ module Autoproj
526
537
  # Returns the set of packages that are actually selected based on what
527
538
  # the user gave on the command line
528
539
  def self.resolve_user_selection(selected_packages, options = Hash.new)
529
- manifest = Autoproj.manifest
530
-
531
540
  if selected_packages.empty?
532
541
  return manifest.default_packages
533
542
  end
@@ -576,27 +585,56 @@ module Autoproj
576
585
  root = !reason
577
586
  chain.unshift pkg_name
578
587
  if root
579
- reason = Autoproj.manifest.exclusion_reason(pkg_name)
588
+ reason = manifest.exclusion_reason(pkg_name)
580
589
  else
581
590
  if chain.size == 1
582
- Autoproj.manifest.add_exclusion(pkg_name, "its dependency #{reason}")
591
+ manifest.add_exclusion(pkg_name, "its dependency #{reason}")
583
592
  else
584
- Autoproj.manifest.add_exclusion(pkg_name, "#{reason} (dependency chain: #{chain.join(">")})")
593
+ manifest.add_exclusion(pkg_name, "#{reason} (dependency chain: #{chain.join(">")})")
585
594
  end
586
595
  end
587
596
 
588
597
  return if !revdeps.has_key?(pkg_name)
589
598
  revdeps[pkg_name].each do |dep_name|
590
- if !Autoproj.manifest.excluded?(dep_name)
599
+ if !manifest.excluded?(dep_name)
591
600
  mark_exclusion_along_revdeps(dep_name, revdeps, chain.dup, reason)
592
601
  end
593
602
  end
594
603
  end
595
604
 
596
- def self.import_packages(selection)
605
+ def self.import_next_step(manifest, pkg, reverse_dependencies)
606
+ new_packages = []
607
+ pkg.dependencies.each do |dep_name|
608
+ reverse_dependencies[dep_name] << pkg.name
609
+ new_packages << manifest.find_autobuild_package(dep_name)
610
+ end
611
+ pkg_opt_deps, _ = pkg.partition_optional_dependencies
612
+ pkg_opt_deps.each do |dep_name|
613
+ new_packages << manifest.find_autobuild_package(dep_name)
614
+ end
615
+
616
+ new_packages.delete_if do |new_pkg|
617
+ if manifest.excluded?(new_pkg.name)
618
+ mark_exclusion_along_revdeps(new_pkg.name, reverse_dependencies)
619
+ true
620
+ elsif manifest.ignored?(new_pkg.name)
621
+ true
622
+ end
623
+ end
624
+ new_packages
625
+ end
626
+
627
+ def self.import_packages(selection, options = Hash.new)
628
+ options, import_options = Kernel.filter_options options,
629
+ warn_about_ignored_packages: true,
630
+ warn_about_excluded_packages: true
631
+ import_options = Hash[only_local: only_local?, reset: reset?, checkout_only: !Autobuild.do_update].
632
+ merge(import_options)
633
+
634
+ updated_packages = Array.new
597
635
  selected_packages = selection.packages.
598
636
  map do |pkg_name|
599
- pkg = Autobuild::Package[pkg_name]
637
+ pkg = manifest.find_autobuild_package(pkg_name)
600
638
  if !pkg
601
639
  raise ConfigError.new, "selected package #{pkg_name} does not exist"
602
640
  end
@@ -626,21 +664,33 @@ module Autoproj
626
664
  raise ConfigError.new, "#{pkg.name} has no VCS, but is not checked out in #{pkg.srcdir}"
627
665
  end
628
666
 
667
+ # Try to auto-exclude the package early. If the autobuild file
668
+ # contained some information that allows us to exclude it now,
669
+ # then let's just do it
670
+ import_next_step(manifest, pkg, reverse_dependencies)
671
+ if manifest.excluded?(pkg.name)
672
+ selection.filter_excluded_and_ignored_packages(manifest)
673
+ next
674
+ end
675
+
629
676
  ## COMPLETELY BYPASS RAKE HERE
630
677
  # The reason is that the ordering of import/prepare between
631
678
  # packages is not important BUT the ordering of import vs.
632
679
  # prepare in one package IS important: prepare is the method
633
680
  # that takes into account dependencies.
634
- pkg.import(only_local?)
681
+ pkg.import(import_options)
682
+ if pkg.updated?
683
+ updated_packages << pkg.name
684
+ end
635
685
  Rake::Task["#{pkg.name}-import"].instance_variable_set(:@already_invoked, true)
636
686
  manifest.load_package_manifest(pkg.name)
637
687
 
638
688
  # The package setup mechanisms might have added an exclusion
639
689
  # on this package. Handle this.
640
- if Autoproj.manifest.excluded?(pkg.name)
690
+ if manifest.excluded?(pkg.name)
641
691
  mark_exclusion_along_revdeps(pkg.name, reverse_dependencies)
642
692
  # Run a filter now, to have errors as early as possible
643
- selection.filter_excluded_and_ignored_packages(Autoproj.manifest)
693
+ selection.filter_excluded_and_ignored_packages(manifest)
644
694
  # Delete this package from the current_packages set
645
695
  next
646
696
  end
@@ -650,32 +700,17 @@ module Autoproj
650
700
  end
651
701
  pkg.update_environment
652
702
 
653
- # Verify that its dependencies are there, and add
654
- # them to the selected_packages set so that they get
655
- # imported as well
656
- new_packages = []
657
- pkg.dependencies.each do |dep_name|
658
- reverse_dependencies[dep_name] << pkg.name
659
- new_packages << Autobuild::Package[dep_name]
660
- end
661
- pkg_opt_deps, _ = pkg.partition_optional_dependencies
662
- pkg_opt_deps.each do |dep_name|
663
- new_packages << Autobuild::Package[dep_name]
664
- end
665
-
666
- new_packages.delete_if do |pkg|
667
- if Autoproj.manifest.excluded?(pkg.name)
668
- mark_exclusion_along_revdeps(pkg.name, reverse_dependencies)
669
- true
670
- elsif Autoproj.manifest.ignored?(pkg.name)
671
- true
672
- end
703
+ new_packages = import_next_step(manifest, pkg, reverse_dependencies)
704
+ # Excluded dependencies might have caused the package to be
705
+ # excluded as well ... do not add any dependency to the
706
+ # processing queue if it is the case
707
+ if !manifest.excluded?(pkg.name)
708
+ package_queue.concat(new_packages.sort_by(&:name))
673
709
  end
674
- package_queue.concat(new_packages.sort_by(&:name))
675
710
 
676
711
  # Verify that everything is still OK with the new
677
712
  # exclusions/ignores
678
- selection.filter_excluded_and_ignored_packages(Autoproj.manifest)
713
+ selection.filter_excluded_and_ignored_packages(manifest)
679
714
  end
680
715
 
681
716
  all_enabled_packages = Set.new
@@ -720,18 +755,35 @@ module Autoproj
720
755
  end
721
756
  end
722
757
 
723
- selection.exclusions.each do |sel, pkg_names|
724
- pkg_names.sort.each do |pkg_name|
725
- Autoproj.warn "#{pkg_name}, which was selected for #{sel}, cannot be built: #{Autoproj.manifest.exclusion_reason(pkg_name)}", :bold
758
+ if options[:warn_about_excluded_packages]
759
+ selection.exclusions.each do |sel, pkg_names|
760
+ pkg_names.sort.each do |pkg_name|
761
+ Autoproj.warn "#{pkg_name}, which was selected for #{sel}, cannot be built: #{manifest.exclusion_reason(pkg_name)}", :bold
762
+ end
726
763
  end
727
764
  end
728
- selection.ignores.each do |sel, pkg_names|
729
- pkg_names.sort.each do |pkg_name|
730
- Autoproj.warn "#{pkg_name}, which was selected for #{sel}, is ignored", :bold
765
+ if options[:warn_about_ignored_packages]
766
+ selection.ignores.each do |sel, pkg_names|
767
+ pkg_names.sort.each do |pkg_name|
768
+ Autoproj.warn "#{pkg_name}, which was selected for #{sel}, is ignored", :bold
769
+ end
731
770
  end
732
771
  end
733
772
 
734
773
  return all_enabled_packages
774
+
775
+ ensure
776
+ if !updated_packages.empty?
777
+ failure_message =
778
+ if $!
779
+ " (#{$!.message.split("\n").first})"
780
+ end
781
+ ops = Ops::Snapshot.new(manifest, keep_going: true)
782
+
783
+ ops.update_package_import_state(
784
+ "#{$0} #{argv.join(" ")}#{failure_message}",
785
+ updated_packages)
786
+ end
735
787
  end
736
788
 
737
789
  def self.build_packages(selected_packages, all_enabled_packages, phases = [])
@@ -779,6 +831,7 @@ module Autoproj
779
831
  def self.manifest; Autoproj.manifest end
780
832
  def self.only_status?; !!@only_status end
781
833
  def self.only_local?; !!@only_local end
834
+ def self.reset?; !!@reset end
782
835
  def self.check?; !!@check end
783
836
  def self.manifest_update?; !!@manifest_update end
784
837
  def self.only_config?; !!@only_config end
@@ -846,6 +899,7 @@ module Autoproj
846
899
  @force_re_build_with_depends = false
847
900
  force_re_build_with_depends = nil
848
901
  @only_config = false
902
+ @reset = false
849
903
  @color = true
850
904
  Autobuild.color = true
851
905
  Autobuild.do_update = nil
@@ -997,9 +1051,13 @@ where 'mode' is one of:
997
1051
  opts.on("--none", "in osdeps mode, do not install any package but display information about them, regardless of the otherwise selected mode") do
998
1052
  @osdeps_forced_mode = 'none'
999
1053
  end
1000
- opts.on("--local", "for status, do not access the network") do
1054
+ opts.on("--local", "in status and update modes, do not access the network") do
1001
1055
  @only_local = true
1002
1056
  end
1057
+ opts.on("--reset", "in update mode, reset the repositories to the state requested by the VCS configuration") do
1058
+ @reset = true
1059
+ end
1060
+
1003
1061
  opts.on('--exit-code', 'in status mode, exit with a code that reflects the status of the installation (see documentation for details)') do
1004
1062
  @status_exit_code = true
1005
1063
  end
@@ -1255,7 +1313,7 @@ where 'mode' is one of:
1255
1313
  end
1256
1314
 
1257
1315
  def self.status(packages)
1258
- pkg_sets = Autoproj.manifest.each_package_set.map(&:create_autobuild_package)
1316
+ pkg_sets = manifest.each_package_set.map(&:create_autobuild_package)
1259
1317
  if !pkg_sets.empty?
1260
1318
  Autoproj.message("autoproj: displaying status of configuration", :bold)
1261
1319
  display_status(pkg_sets)
@@ -1270,7 +1328,7 @@ where 'mode' is one of:
1270
1328
  end
1271
1329
 
1272
1330
  def self.missing_dependencies(pkg)
1273
- manifest = Autoproj.manifest.package_manifests[pkg.name]
1331
+ manifest = manifest.package_manifests[pkg.name]
1274
1332
  all_deps = pkg.dependencies.map do |dep_name|
1275
1333
  dep_pkg = Autobuild::Package[dep_name]
1276
1334
  if dep_pkg then dep_pkg.name
@@ -1298,7 +1356,7 @@ where 'mode' is one of:
1298
1356
  result = []
1299
1357
 
1300
1358
  pkg = Autobuild::Package[pkg_name]
1301
- manifest = Autoproj.manifest.package_manifests[pkg.name]
1359
+ manifest = manifest.package_manifests[pkg.name]
1302
1360
 
1303
1361
  # Check if the manifest contains rosdep tags
1304
1362
  # if manifest && !manifest.each_os_dependency.to_a.empty?
@@ -1320,7 +1378,7 @@ where 'mode' is one of:
1320
1378
  def self.manifest_update(packages)
1321
1379
  packages.sort.each do |pkg_name|
1322
1380
  pkg = Autobuild::Package[pkg_name]
1323
- manifest = Autoproj.manifest.package_manifests[pkg.name]
1381
+ manifest = manifest.package_manifests[pkg.name]
1324
1382
 
1325
1383
  xml =
1326
1384
  if !manifest
@@ -1358,87 +1416,10 @@ where 'mode' is one of:
1358
1416
  end
1359
1417
  end
1360
1418
 
1361
- def self.snapshot(manifest, target_dir, packages)
1362
- # First, copy the configuration directory to create target_dir
1363
- if File.exists?(target_dir)
1364
- raise ArgumentError, "#{target_dir} already exists"
1365
- end
1366
- FileUtils.cp_r Autoproj.config_dir, target_dir
1367
- # Finally, remove the remotes/ directory from the generated
1368
- # buildconf, it is obsolete now
1369
- FileUtils.rm_rf File.join(target_dir, 'remotes')
1370
-
1371
- # Pin package sets
1372
- package_sets = Array.new
1373
- manifest.each_package_set do |pkg_set|
1374
- next if pkg_set.name == 'local'
1375
- if pkg_set.local?
1376
- package_sets << Pathname.new(pkg_set.local_dir).
1377
- relative_path_from(Pathname.new(manifest.file).dirname).
1378
- to_s
1379
- else
1380
- vcs_info = pkg_set.vcs.to_hash
1381
- if pin_info = pkg_set.snapshot(target_dir)
1382
- vcs_info = vcs_info.merge(pin_info)
1383
- end
1384
- package_sets << vcs_info
1385
- end
1386
- end
1387
- manifest_path = File.join(target_dir, 'manifest')
1388
- manifest_data = YAML.load(File.read(manifest_path))
1389
- manifest_data['package_sets'] = package_sets
1390
- File.open(manifest_path, 'w') do |io|
1391
- YAML.dump(manifest_data, io)
1392
- end
1393
-
1394
- # Now, create snapshot information for each of the packages
1395
- version_control_info = []
1396
- overrides_info = []
1397
- packages.each do |package_name|
1398
- package = manifest.packages[package_name]
1399
- if !package
1400
- raise ArgumentError, "#{package_name} is not a known package"
1401
- end
1402
- package_set = package.package_set
1403
- importer = package.autobuild.importer
1404
- if !importer
1405
- Autoproj.message "cannot snapshot #{package_name} as it has no importer"
1406
- next
1407
- elsif !importer.respond_to?(:snapshot)
1408
- Autoproj.message "cannot snapshot #{package_name} as the #{importer.class} importer does not support it"
1409
- next
1410
- end
1411
-
1412
- vcs_info = importer.snapshot(package.autobuild, target_dir)
1413
- if vcs_info
1414
- if package_set.name == 'local'
1415
- version_control_info << Hash[package_name, vcs_info]
1416
- else
1417
- overrides_info << Hash[package_name, vcs_info]
1418
- end
1419
- end
1420
- end
1421
-
1422
- overrides_path = File.join(target_dir, 'overrides.yml')
1423
- if File.exists?(overrides_path)
1424
- overrides = YAML.load(File.read(overrides_path))
1425
- end
1426
- # In Ruby 1.9, an empty file results in YAML.load returning false
1427
- overrides ||= Hash.new
1428
- (overrides['version_control'] ||= Array.new).
1429
- concat(version_control_info)
1430
- (overrides['overrides'] ||= Array.new).
1431
- concat(overrides_info)
1432
-
1433
- File.open(overrides_path, 'w') do |io|
1434
- io.write YAML.dump(overrides)
1435
- end
1436
- end
1437
-
1438
1419
  # Displays the reverse OS dependencies (i.e. for each osdeps package,
1439
1420
  # who depends on it and where it is defined)
1440
1421
  def self.revshow_osdeps(packages)
1441
- _, ospkg_to_pkg = Autoproj.manifest.list_os_dependencies(packages)
1422
+ _, ospkg_to_pkg = manifest.list_os_dependencies(packages)
1442
1423
 
1443
1424
  # A mapping from a package name to
1444
1425
  # [is_os_pkg, is_gem_pkg, definitions, used_by]
@@ -1489,7 +1470,7 @@ where 'mode' is one of:
1489
1470
 
1490
1471
  # Displays the OS dependencies required by the given packages
1491
1472
  def self.show_osdeps(packages)
1492
- _, ospkg_to_pkg = Autoproj.manifest.list_os_dependencies(packages)
1473
+ _, ospkg_to_pkg = manifest.list_os_dependencies(packages)
1493
1474
 
1494
1475
  # ospkg_to_pkg is the reverse mapping to what we want. Invert it
1495
1476
  mapping = Hash.new { |h, k| h[k] = Set.new }
@@ -1546,6 +1527,7 @@ where 'mode' is one of:
1546
1527
  Autoproj::CmdLine.setup_all_package_directories
1547
1528
  Autoproj::CmdLine.finalize_package_setup
1548
1529
 
1530
+
1549
1531
  load_all_available_package_manifests
1550
1532
  update_environment
1551
1533
  remaining_arguments
@@ -1609,18 +1591,23 @@ where 'mode' is one of:
1609
1591
 
1610
1592
  def self.export_installation_manifest
1611
1593
  File.open(File.join(Autoproj.root_dir, ".autoproj-installation-manifest"), 'w') do |io|
1612
- Autoproj.manifest.all_selected_packages.each do |pkg_name|
1594
+ manifest.all_selected_packages.each do |pkg_name|
1613
1595
  pkg = Autobuild::Package[pkg_name]
1614
1596
  io.puts "#{pkg_name},#{pkg.srcdir},#{pkg.prefix}"
1615
1597
  end
1616
1598
  end
1617
1599
  end
1618
1600
 
1619
- def self.report
1601
+ def self.report(options = Hash.new)
1602
+ options = Kernel.validate_options options,
1603
+ silent: false
1604
+
1620
1605
  Autobuild::Reporting.report do
1621
1606
  yield
1622
1607
  end
1623
- Autobuild::Reporting.success
1608
+ if !options[:silent]
1609
+ Autobuild::Reporting.success
1610
+ end
1624
1611
 
1625
1612
  rescue ConfigError => e
1626
1613
  STDERR.puts