beaker-puppet 1.29.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +9 -0
  3. data/.github/workflows/release.yml +2 -2
  4. data/.github/workflows/test.yml +28 -7
  5. data/.rubocop.yml +5 -0
  6. data/.rubocop_todo.yml +842 -0
  7. data/CHANGELOG.md +31 -0
  8. data/Gemfile +5 -20
  9. data/Rakefile +64 -169
  10. data/acceptance/config/acceptance-options.rb +3 -3
  11. data/acceptance/config/gem/acceptance-options.rb +8 -8
  12. data/acceptance/config/git/acceptance-options.rb +8 -8
  13. data/acceptance/config/pkg/acceptance-options.rb +7 -7
  14. data/acceptance/pre_suite/gem/install.rb +6 -6
  15. data/acceptance/pre_suite/git/install.rb +22 -22
  16. data/acceptance/pre_suite/pkg/install.rb +3 -3
  17. data/acceptance/tests/backwards_compatible.rb +6 -7
  18. data/acceptance/tests/clone_git_repo_on_test.rb +12 -13
  19. data/acceptance/tests/create_tmpdir_on_test.rb +13 -9
  20. data/acceptance/tests/install_smoke_test.rb +5 -4
  21. data/acceptance/tests/stub_host.rb +11 -10
  22. data/acceptance/tests/web_helpers_test.rb +11 -10
  23. data/beaker-puppet.gemspec +16 -23
  24. data/bin/beaker-puppet +2 -4
  25. data/lib/beaker-puppet/helpers/facter_helpers.rb +9 -7
  26. data/lib/beaker-puppet/helpers/host_helpers.rb +10 -7
  27. data/lib/beaker-puppet/helpers/puppet_helpers.rb +151 -160
  28. data/lib/beaker-puppet/helpers/rake_helpers.rb +1 -1
  29. data/lib/beaker-puppet/helpers/tk_helpers.rb +22 -28
  30. data/lib/beaker-puppet/install_utils/aio_defaults.rb +39 -43
  31. data/lib/beaker-puppet/install_utils/ezbake_utils.rb +34 -42
  32. data/lib/beaker-puppet/install_utils/foss_defaults.rb +134 -138
  33. data/lib/beaker-puppet/install_utils/foss_utils.rb +293 -320
  34. data/lib/beaker-puppet/install_utils/module_utils.rb +58 -70
  35. data/lib/beaker-puppet/install_utils/puppet5.rb +30 -35
  36. data/lib/beaker-puppet/install_utils/puppet_utils.rb +58 -68
  37. data/lib/beaker-puppet/install_utils/windows_utils.rb +34 -36
  38. data/lib/beaker-puppet/version.rb +1 -1
  39. data/lib/beaker-puppet/wrappers.rb +13 -14
  40. data/lib/beaker-puppet.rb +4 -5
  41. data/setup/aio/010_Install_Puppet_Agent.rb +5 -6
  42. data/setup/common/000-delete-puppet-when-none.rb +2 -4
  43. data/setup/common/003_solaris_cert_fix.rb +74 -70
  44. data/setup/common/005_redhat_subscription_fix.rb +3 -2
  45. data/setup/common/011_Install_Puppet_Server.rb +7 -9
  46. data/setup/common/012_Finalize_Installs.rb +5 -5
  47. data/setup/common/025_StopFirewall.rb +1 -1
  48. data/setup/common/030_StopSssd.rb +2 -2
  49. data/setup/common/040_ValidateSignCert.rb +10 -12
  50. data/setup/common/045_EnsureMasterStarted.rb +2 -2
  51. data/setup/gem/010_GemInstall.rb +5 -4
  52. data/setup/git/000_EnvSetup.rb +48 -48
  53. data/setup/git/010_TestSetup.rb +13 -12
  54. data/setup/git/020_PuppetUserAndGroup.rb +3 -2
  55. data/setup/git/060_InstallModules.rb +14 -14
  56. data/setup/git/070_InstallCACerts.rb +82 -82
  57. data/spec/beaker-puppet/helpers/facter_helpers_spec.rb +22 -24
  58. data/spec/beaker-puppet/helpers/host_helpers_spec.rb +10 -6
  59. data/spec/beaker-puppet/helpers/puppet_helpers_spec.rb +506 -517
  60. data/spec/beaker-puppet/helpers/tk_helpers_spec.rb +20 -24
  61. data/spec/beaker-puppet/install_utils/ezbake_utils_spec.rb +86 -90
  62. data/spec/beaker-puppet/install_utils/foss_utils_spec.rb +636 -599
  63. data/spec/beaker-puppet/install_utils/module_utils_spec.rb +125 -116
  64. data/spec/beaker-puppet/install_utils/puppet5_spec.rb +159 -165
  65. data/spec/beaker-puppet/install_utils/puppet_utils_spec.rb +92 -77
  66. data/spec/beaker-puppet/install_utils/windows_utils_spec.rb +101 -89
  67. data/spec/beaker-puppet/wrappers_spec.rb +10 -10
  68. data/spec/helpers.rb +85 -91
  69. data/tasks/ci.rake +171 -179
  70. metadata +33 -62
  71. data/setup/common/020_InstallCumulusModules.rb +0 -13
  72. data/setup/common/021_InstallAristaModuleMasters.rb +0 -12
  73. data/setup/common/022_InstallAristaModuleAgents.rb +0 -13
@@ -7,7 +7,7 @@ module Beaker
7
7
  def load_tasks(beaker_root = File.expand_path("#{__dir__}/../../.."))
8
8
  task_dir = File.join(beaker_root, 'tasks')
9
9
  tasks = [
10
- 'ci.rake'
10
+ 'ci.rake',
11
11
  ]
12
12
 
13
13
  tasks.each do |task|
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  require 'hocon'
3
2
  require 'hocon/config_error'
4
3
  require 'inifile'
@@ -8,7 +7,6 @@ module Beaker
8
7
  module Helpers
9
8
  # Convenience methods for modifying and reading TrapperKeeper configs
10
9
  module TKHelpers
11
-
12
10
  # Modify the given TrapperKeeper config file.
13
11
  #
14
12
  # @param [Host] host A host object
@@ -25,20 +23,17 @@ module Beaker
25
23
  # particularly care which of these the file named by `config_file_path` on
26
24
  # the SUT actually is, just that the contents can be parsed into a map.
27
25
  #
28
- def modify_tk_config(host, config_file_path, options_hash, replace=false)
29
- if options_hash.empty?
30
- return nil
31
- end
26
+ def modify_tk_config(host, config_file_path, options_hash, replace = false)
27
+ return nil if options_hash.empty?
32
28
 
33
29
  new_hash = Beaker::Options::OptionsHash.new
34
30
 
35
31
  if replace
36
32
  new_hash.merge!(options_hash)
37
33
  else
38
- if not host.file_exist?( config_file_path )
39
- raise "Error: #{config_file_path} does not exist on #{host}"
40
- end
41
- file_string = host.exec( Command.new( "cat #{config_file_path}" )).stdout
34
+ raise "Error: #{config_file_path} does not exist on #{host}" unless host.file_exist?(config_file_path)
35
+
36
+ file_string = host.exec(Command.new("cat #{config_file_path}")).stdout
42
37
 
43
38
  begin
44
39
  tk_conf_hash = read_tk_config_string(file_string)
@@ -61,29 +56,28 @@ module Beaker
61
56
  # a RuntimeException if none of the parsers succeed.
62
57
  #
63
58
  # @!visibility private
64
- def read_tk_config_string( string )
65
- begin
66
- return Hocon.parse(string)
67
- rescue Hocon::ConfigError
68
- nil
69
- end
59
+ def read_tk_config_string(string)
60
+ begin
61
+ return Hocon.parse(string)
62
+ rescue Hocon::ConfigError
63
+ nil
64
+ end
70
65
 
71
- begin
72
- return JSON.parse(string)
73
- rescue JSON::JSONError
74
- nil
75
- end
66
+ begin
67
+ return JSON.parse(string)
68
+ rescue JSON::JSONError
69
+ nil
70
+ end
76
71
 
77
- begin
78
- return IniFile.new(content: string)
79
- rescue IniFile::Error
80
- nil
81
- end
72
+ begin
73
+ return IniFile.new(content: string)
74
+ rescue IniFile::Error
75
+ nil
76
+ end
82
77
 
83
- raise "Failed to read TrapperKeeper config!"
78
+ raise 'Failed to read TrapperKeeper config!'
84
79
  end
85
80
  end
86
-
87
81
  end
88
82
  end
89
83
  end
@@ -5,15 +5,14 @@ module Beaker
5
5
  # This module contains default values for aio paths and directorys per-platform
6
6
  #
7
7
  module AIODefaults
8
-
9
- #Here be the pathing and default values for AIO installs
8
+ # Here be the pathing and default values for AIO installs
10
9
  #
11
10
  AIO_DEFAULTS = {
12
11
  'unix' => {
13
- 'puppetbindir' => '/opt/puppetlabs/bin',
14
- 'privatebindir' => '/opt/puppetlabs/puppet/bin',
15
- 'distmoduledir' => '/etc/puppetlabs/code/modules',
16
- 'sitemoduledir' => '/opt/puppetlabs/puppet/modules',
12
+ 'puppetbindir' => '/opt/puppetlabs/bin',
13
+ 'privatebindir' => '/opt/puppetlabs/puppet/bin',
14
+ 'distmoduledir' => '/etc/puppetlabs/code/modules',
15
+ 'sitemoduledir' => '/opt/puppetlabs/puppet/modules',
17
16
  },
18
17
  # sitemoduledir not included on Windows (check PUP-4049 for more info).
19
18
  #
@@ -23,20 +22,20 @@ module Beaker
23
22
  # include sys/ruby) and the newer versions, which have no custom ruby
24
23
  # directory
25
24
  'windows' => { # windows with cygwin
26
- 'puppetbindir' => '/cygdrive/c/Program Files (x86)/Puppet Labs/Puppet/bin',
27
- 'privatebindir' => '/cygdrive/c/Program Files (x86)/Puppet Labs/Puppet/puppet/bin:/cygdrive/c/Program Files (x86)/Puppet Labs/Puppet/sys/ruby/bin',
28
- 'distmoduledir' => '`cygpath -smF 35`/PuppetLabs/code/modules',
25
+ 'puppetbindir' => '/cygdrive/c/Program Files (x86)/Puppet Labs/Puppet/bin',
26
+ 'privatebindir' => '/cygdrive/c/Program Files (x86)/Puppet Labs/Puppet/puppet/bin:/cygdrive/c/Program Files (x86)/Puppet Labs/Puppet/sys/ruby/bin',
27
+ 'distmoduledir' => '`cygpath -smF 35`/PuppetLabs/code/modules',
29
28
  },
30
29
  'windows-64' => { # windows with cygwin
31
- 'puppetbindir' => '/cygdrive/c/Program Files/Puppet Labs/Puppet/bin',
32
- 'privatebindir' => '/cygdrive/c/Program Files/Puppet Labs/Puppet/puppet/bin:/cygdrive/c/Program Files/Puppet Labs/Puppet/sys/ruby/bin',
33
- 'distmoduledir' => '`cygpath -smF 35`/PuppetLabs/code/modules',
30
+ 'puppetbindir' => '/cygdrive/c/Program Files/Puppet Labs/Puppet/bin',
31
+ 'privatebindir' => '/cygdrive/c/Program Files/Puppet Labs/Puppet/puppet/bin:/cygdrive/c/Program Files/Puppet Labs/Puppet/sys/ruby/bin',
32
+ 'distmoduledir' => '`cygpath -smF 35`/PuppetLabs/code/modules',
34
33
  },
35
34
  'pswindows' => { # pure windows
36
- 'puppetbindir' => '"C:\\Program Files (x86)\\Puppet Labs\\Puppet\\bin";"C:\\Program Files\\Puppet Labs\\Puppet\\bin"',
37
- 'privatebindir' => '"C:\\Program Files (x86)\\Puppet Labs\\Puppet\\puppet\\bin";"C:\\Program Files\\Puppet Labs\\Puppet\\puppet\\bin";"C:\\Program Files (x86)\\Puppet Labs\\Puppet\\sys\\ruby\\bin";"C:\\Program Files\\Puppet Labs\\Puppet\\sys\\ruby\\bin"',
38
- 'distmoduledir' => 'C:\\ProgramData\\PuppetLabs\\code\\modules',
39
- }
35
+ 'puppetbindir' => '"C:\\Program Files (x86)\\Puppet Labs\\Puppet\\bin";"C:\\Program Files\\Puppet Labs\\Puppet\\bin"',
36
+ 'privatebindir' => '"C:\\Program Files (x86)\\Puppet Labs\\Puppet\\puppet\\bin";"C:\\Program Files\\Puppet Labs\\Puppet\\puppet\\bin";"C:\\Program Files (x86)\\Puppet Labs\\Puppet\\sys\\ruby\\bin";"C:\\Program Files\\Puppet Labs\\Puppet\\sys\\ruby\\bin"',
37
+ 'distmoduledir' => 'C:\\ProgramData\\PuppetLabs\\code\\modules',
38
+ },
40
39
  }
41
40
 
42
41
  # Add the appropriate aio defaults to the host object so that they can be accessed using host[option], set host[:type] = aio
@@ -47,31 +46,31 @@ module Beaker
47
46
  host[key] = val
48
47
  end
49
48
  # add group and type here for backwards compatability
50
- if host['platform'] =~ /windows/
51
- host['group'] = 'Administrators'
52
- else
53
- host['group'] = 'puppet'
54
- end
49
+ host['group'] = if host['platform'] =~ /windows/
50
+ 'Administrators'
51
+ else
52
+ 'puppet'
53
+ end
55
54
  end
56
55
 
57
56
  # Add the appropriate aio defaults to an array of hosts
58
57
  # @param [Host, Array<Host>, String, Symbol] hosts One or more hosts to act upon,
59
58
  # or a role (String or Symbol) that identifies one or more hosts.
60
59
  def add_aio_defaults_on(hosts)
61
- block_on hosts do | host |
60
+ block_on hosts do |host|
62
61
  if host.is_powershell?
63
62
  platform = 'pswindows'
64
63
  elsif host['platform'] =~ /windows/
65
- if host[:ruby_arch] == 'x64'
66
- ruby_arch = /-64/
67
- else
68
- ruby_arch = /-32/
69
- end
70
- if host['platform'] =~ ruby_arch
71
- platform = 'windows-64'
72
- else
73
- platform = 'windows'
74
- end
64
+ ruby_arch = if host[:ruby_arch] == 'x64'
65
+ /-64/
66
+ else
67
+ /-32/
68
+ end
69
+ platform = if host['platform'] =~ ruby_arch
70
+ 'windows-64'
71
+ else
72
+ 'windows'
73
+ end
75
74
  else
76
75
  platform = 'unix'
77
76
  end
@@ -93,21 +92,18 @@ module Beaker
93
92
  # @param [Host, Array<Host>, String, Symbol] hosts One or more hosts to act upon,
94
93
  # or a role (String or Symbol) that identifies one or more hosts.
95
94
  def remove_aio_defaults_on(hosts)
96
- block_on hosts do | host |
97
- if host.is_powershell?
98
- platform = 'pswindows'
99
- elsif host['platform'] =~ /windows/
100
- platform = 'windows'
101
- else
102
- platform = 'unix'
103
- end
95
+ block_on hosts do |host|
96
+ platform = if host.is_powershell?
97
+ 'pswindows'
98
+ elsif host['platform'] =~ /windows/
99
+ 'windows'
100
+ else
101
+ 'unix'
102
+ end
104
103
  remove_platform_aio_defaults(host, platform)
105
104
  end
106
105
  end
107
-
108
-
109
106
  end
110
107
  end
111
108
  end
112
109
  end
113
-
@@ -7,29 +7,28 @@ module Beaker
7
7
  # that use ezbake for packaging.
8
8
  #
9
9
  module EZBakeUtils
10
-
11
10
  # @!group Public DSL Methods
12
11
 
13
12
  # Installs leiningen project with given name and version on remote host.
14
13
  #
15
14
  # @param [Host] host A single remote host on which to install the
16
15
  # specified leiningen project.
17
- def install_from_ezbake host
16
+ def install_from_ezbake(host)
18
17
  ezbake_validate_support host
19
18
  ezbake_tools_available?
20
19
  install_ezbake_tarball_on_host host
21
- ezbake_installsh host, "service"
20
+ ezbake_installsh host, 'service'
22
21
  end
23
22
 
24
23
  # Installs termini with given name and version on remote host.
25
24
  #
26
25
  # @param [Host] host A single remote host on which to install the
27
26
  # specified leiningen project.
28
- def install_termini_from_ezbake host
27
+ def install_termini_from_ezbake(host)
29
28
  ezbake_validate_support host
30
29
  ezbake_tools_available?
31
30
  install_ezbake_tarball_on_host host
32
- ezbake_installsh host, "termini"
31
+ ezbake_installsh host, 'termini'
33
32
  end
34
33
 
35
34
  # Install a development version of ezbake into the local m2 repository
@@ -42,15 +41,15 @@ module Beaker
42
41
  #
43
42
  # @param url [String] git url
44
43
  # @param branch [String] git branch
45
- def ezbake_dev_build url = "git@github.com:puppetlabs/ezbake.git",
46
- branch = "master"
44
+ def ezbake_dev_build(url = 'git@github.com:puppetlabs/ezbake.git',
45
+ branch = 'master')
47
46
  ezbake_dir = 'tmp/ezbake'
48
47
  conditionally_clone url, ezbake_dir, branch
49
48
  lp = ezbake_lein_prefix
50
49
 
51
50
  Dir.chdir(ezbake_dir) do
52
51
  ezbake_local_cmd "#{lp} install",
53
- :throw_on_failure => true
52
+ throw_on_failure: true
54
53
  end
55
54
  end
56
55
 
@@ -67,25 +66,22 @@ module Beaker
67
66
  # @param [Host] host host to check for support
68
67
  # @raise [RuntimeError] if OS is not supported
69
68
  # @api private
70
- def ezbake_validate_support host
71
- variant, version, _, _ = host['platform'].to_array
72
- unless variant =~ /^(fedora|el|redhat|centos|debian|ubuntu)$/
73
- raise RuntimeError,
74
- "No support for #{variant} within ezbake_utils ..."
75
- end
69
+ def ezbake_validate_support(host)
70
+ variant, version, = host['platform'].to_array
71
+ return if variant =~ /^(fedora|el|redhat|centos|debian|ubuntu)$/
72
+
73
+ raise "No support for #{variant} within ezbake_utils ..."
76
74
  end
77
75
 
78
76
  # Build, copy & unpack tarball on remote host
79
77
  #
80
78
  # @param [Host] host installation destination
81
79
  # @api private
82
- def install_ezbake_tarball_on_host host
83
- if not ezbake_config
84
- ezbake_stage
85
- end
80
+ def install_ezbake_tarball_on_host(host)
81
+ ezbake_stage unless ezbake_config
86
82
 
87
83
  # Skip installation if the remote directory exists
88
- result = on host, "test -d #{ezbake_install_dir}", :acceptable_exit_codes => [0, 1]
84
+ result = on host, "test -d #{ezbake_install_dir}", acceptable_exit_codes: [0, 1]
89
85
  return if result.exit_code == 0
90
86
 
91
87
  ezbake_staging_dir = File.join('target', 'staging')
@@ -93,12 +89,12 @@ module Beaker
93
89
  ezbake_local_cmd 'rake package:tar'
94
90
  end
95
91
 
96
- local_tarball = ezbake_staging_dir + "/pkg/" + ezbake_install_name + ".tar.gz"
97
- remote_tarball = ezbake_install_dir + ".tar.gz"
92
+ local_tarball = ezbake_staging_dir + '/pkg/' + ezbake_install_name + '.tar.gz'
93
+ remote_tarball = ezbake_install_dir + '.tar.gz'
98
94
  scp_to host, local_tarball, remote_tarball
99
95
 
100
96
  # untar tarball on host
101
- on host, "tar -xzf " + remote_tarball
97
+ on host, 'tar -xzf ' + remote_tarball
102
98
 
103
99
  # Check to ensure directory exists
104
100
  on host, "test -d #{ezbake_install_dir}"
@@ -107,7 +103,7 @@ module Beaker
107
103
  LOCAL_COMMANDS_REQUIRED = [
108
104
  ['leiningen', 'lein --version', nil],
109
105
  ['lein-pprint', 'lein with-profile ci pprint :version',
110
- 'Must have lein-pprint installed under the :ci profile.'],
106
+ 'Must have lein-pprint installed under the :ci profile.',],
111
107
  ['java', 'java -version', nil],
112
108
  ['git', 'git --version', nil],
113
109
  ['rake', 'rake --version', nil],
@@ -120,13 +116,11 @@ module Beaker
120
116
  # @api private
121
117
  def ezbake_tools_available?
122
118
  LOCAL_COMMANDS_REQUIRED.each do |software_name, command, additional_error_message|
123
- if not system command
124
- error_message = "Must have #{software_name} installed on development system.\n"
125
- if additional_error_message
126
- error_message += additional_error_message
127
- end
128
- raise RuntimeError, error_message
129
- end
119
+ next if system command
120
+
121
+ error_message = "Must have #{software_name} installed on development system.\n"
122
+ error_message += additional_error_message if additional_error_message
123
+ raise error_message
130
124
  end
131
125
  end
132
126
 
@@ -156,14 +150,14 @@ module Beaker
156
150
  def ezbake_stage
157
151
  # Install the PuppetDB jar into the local repository
158
152
  ezbake_local_cmd "#{ezbake_lein_prefix} install",
159
- :throw_on_failure => true
153
+ throw_on_failure: true
160
154
 
161
155
  # Run ezbake stage
162
156
  ezbake_local_cmd "#{ezbake_lein_prefix} with-profile ezbake ezbake stage",
163
- :throw_on_failure => true
157
+ throw_on_failure: true
164
158
 
165
159
  # Boostrap packaging, and grab configuration info from project
166
- staging_dir = File.join('target','staging')
160
+ staging_dir = File.join('target', 'staging')
167
161
  Dir.chdir(staging_dir) do
168
162
  ezbake_local_cmd 'rake package:bootstrap'
169
163
 
@@ -184,16 +178,15 @@ module Beaker
184
178
  # @raise [RuntimeError] if :throw_on_failure is true and
185
179
  # command fails
186
180
  # @api private
187
- def ezbake_local_cmd cmd, opts={}
181
+ def ezbake_local_cmd(cmd, opts = {})
188
182
  opts = {
189
- :throw_on_failure => false,
183
+ throw_on_failure: false,
190
184
  }.merge(opts)
191
185
 
192
186
  logger.notify "localhost $ #{cmd}"
193
187
  result = system cmd
194
- if opts[:throw_on_failure] && result == false
195
- raise RuntimeError, "Command failure #{cmd}"
196
- end
188
+ raise "Command failure #{cmd}" if opts[:throw_on_failure] && result == false
189
+
197
190
  result
198
191
  end
199
192
 
@@ -207,7 +200,7 @@ module Beaker
207
200
  ezbake = ezbake_config
208
201
  project_package_version = ezbake[:package_version]
209
202
  project_name = ezbake[:project]
210
- "%s-%s" % [ project_name, project_package_version ]
203
+ format('%s-%s', project_name, project_package_version)
211
204
  end
212
205
 
213
206
  # Returns the full path to the installed software on the remote host.
@@ -227,7 +220,7 @@ module Beaker
227
220
  # @param [Host] host Host to run install.sh on
228
221
  # @param [String] task Task to execute with install.sh
229
222
  # @api private
230
- def ezbake_installsh host, task=""
223
+ def ezbake_installsh(host, task = '')
231
224
  on host, "cd #{ezbake_install_dir}; bash install.sh #{task}"
232
225
  end
233
226
 
@@ -238,7 +231,7 @@ module Beaker
238
231
  # @param [String] local_path path to conditionally install to
239
232
  # @param [String] branch to checkout
240
233
  # @api private
241
- def conditionally_clone upstream_uri, local_path, branch="origin/HEAD"
234
+ def conditionally_clone(upstream_uri, local_path, branch = 'origin/HEAD')
242
235
  if ezbake_local_cmd "git --work-tree=#{local_path} --git-dir=#{local_path}/.git status"
243
236
  ezbake_local_cmd "git --work-tree=#{local_path} --git-dir=#{local_path}/.git fetch origin"
244
237
  ezbake_local_cmd "git --work-tree=#{local_path} --git-dir=#{local_path}/.git checkout #{branch}"
@@ -249,7 +242,6 @@ module Beaker
249
242
  ezbake_local_cmd "git --work-tree=#{local_path} --git-dir=#{local_path}/.git checkout #{branch}"
250
243
  end
251
244
  end
252
-
253
245
  end
254
246
  end
255
247
  end