test-kitchen 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/.cane +1 -1
  3. data/.rubocop.yml +3 -0
  4. data/.travis.yml +20 -9
  5. data/CHANGELOG.md +219 -108
  6. data/Gemfile +10 -6
  7. data/Guardfile +38 -9
  8. data/README.md +11 -1
  9. data/Rakefile +21 -37
  10. data/bin/kitchen +4 -4
  11. data/features/kitchen_action_commands.feature +161 -0
  12. data/features/kitchen_console_command.feature +34 -0
  13. data/features/kitchen_diagnose_command.feature +64 -0
  14. data/features/kitchen_init_command.feature +29 -17
  15. data/features/kitchen_list_command.feature +2 -2
  16. data/features/kitchen_login_command.feature +56 -0
  17. data/features/{sink_command.feature → kitchen_sink_command.feature} +0 -0
  18. data/features/kitchen_test_command.feature +88 -0
  19. data/features/step_definitions/gem_steps.rb +8 -6
  20. data/features/step_definitions/git_steps.rb +4 -2
  21. data/features/step_definitions/output_steps.rb +5 -0
  22. data/features/support/env.rb +12 -9
  23. data/lib/kitchen.rb +60 -38
  24. data/lib/kitchen/base64_stream.rb +55 -0
  25. data/lib/kitchen/busser.rb +124 -58
  26. data/lib/kitchen/cli.rb +121 -38
  27. data/lib/kitchen/collection.rb +3 -3
  28. data/lib/kitchen/color.rb +4 -4
  29. data/lib/kitchen/command.rb +78 -11
  30. data/lib/kitchen/command/action.rb +3 -2
  31. data/lib/kitchen/command/console.rb +12 -5
  32. data/lib/kitchen/command/diagnose.rb +17 -3
  33. data/lib/kitchen/command/driver_discover.rb +26 -7
  34. data/lib/kitchen/command/exec.rb +41 -0
  35. data/lib/kitchen/command/list.rb +44 -14
  36. data/lib/kitchen/command/login.rb +2 -1
  37. data/lib/kitchen/command/sink.rb +2 -1
  38. data/lib/kitchen/command/test.rb +5 -4
  39. data/lib/kitchen/config.rb +146 -14
  40. data/lib/kitchen/configurable.rb +314 -0
  41. data/lib/kitchen/data_munger.rb +522 -18
  42. data/lib/kitchen/diagnostic.rb +43 -4
  43. data/lib/kitchen/driver.rb +4 -4
  44. data/lib/kitchen/driver/base.rb +80 -115
  45. data/lib/kitchen/driver/dummy.rb +34 -6
  46. data/lib/kitchen/driver/proxy.rb +14 -3
  47. data/lib/kitchen/driver/ssh_base.rb +61 -7
  48. data/lib/kitchen/errors.rb +109 -9
  49. data/lib/kitchen/generator/driver_create.rb +39 -5
  50. data/lib/kitchen/generator/init.rb +130 -45
  51. data/lib/kitchen/instance.rb +162 -28
  52. data/lib/kitchen/lazy_hash.rb +79 -7
  53. data/lib/kitchen/loader/yaml.rb +159 -27
  54. data/lib/kitchen/logger.rb +267 -21
  55. data/lib/kitchen/logging.rb +30 -3
  56. data/lib/kitchen/login_command.rb +11 -2
  57. data/lib/kitchen/metadata_chopper.rb +2 -2
  58. data/lib/kitchen/provisioner.rb +4 -4
  59. data/lib/kitchen/provisioner/base.rb +107 -103
  60. data/lib/kitchen/provisioner/chef/berkshelf.rb +36 -8
  61. data/lib/kitchen/provisioner/chef/librarian.rb +40 -11
  62. data/lib/kitchen/provisioner/chef_base.rb +206 -167
  63. data/lib/kitchen/provisioner/chef_solo.rb +25 -7
  64. data/lib/kitchen/provisioner/chef_zero.rb +105 -29
  65. data/lib/kitchen/provisioner/dummy.rb +1 -1
  66. data/lib/kitchen/provisioner/shell.rb +21 -6
  67. data/lib/kitchen/rake_tasks.rb +8 -3
  68. data/lib/kitchen/shell_out.rb +15 -18
  69. data/lib/kitchen/ssh.rb +122 -27
  70. data/lib/kitchen/state_file.rb +24 -7
  71. data/lib/kitchen/thor_tasks.rb +9 -4
  72. data/lib/kitchen/util.rb +43 -118
  73. data/lib/kitchen/version.rb +1 -1
  74. data/lib/vendor/hash_recursive_merge.rb +10 -2
  75. data/spec/kitchen/base64_stream_spec.rb +77 -0
  76. data/spec/kitchen/busser_spec.rb +490 -0
  77. data/spec/kitchen/collection_spec.rb +10 -10
  78. data/spec/kitchen/color_spec.rb +2 -2
  79. data/spec/kitchen/config_spec.rb +234 -62
  80. data/spec/kitchen/configurable_spec.rb +490 -0
  81. data/spec/kitchen/data_munger_spec.rb +1070 -862
  82. data/spec/kitchen/diagnostic_spec.rb +79 -0
  83. data/spec/kitchen/driver/base_spec.rb +80 -85
  84. data/spec/kitchen/driver/dummy_spec.rb +43 -14
  85. data/spec/kitchen/driver/proxy_spec.rb +134 -0
  86. data/spec/kitchen/driver/ssh_base_spec.rb +644 -0
  87. data/spec/kitchen/driver_spec.rb +15 -15
  88. data/spec/kitchen/errors_spec.rb +309 -0
  89. data/spec/kitchen/instance_spec.rb +143 -46
  90. data/spec/kitchen/lazy_hash_spec.rb +36 -9
  91. data/spec/kitchen/loader/yaml_spec.rb +237 -226
  92. data/spec/kitchen/logger_spec.rb +419 -0
  93. data/spec/kitchen/logging_spec.rb +59 -0
  94. data/spec/kitchen/login_command_spec.rb +49 -0
  95. data/spec/kitchen/metadata_chopper_spec.rb +82 -0
  96. data/spec/kitchen/platform_spec.rb +4 -4
  97. data/spec/kitchen/provisioner/base_spec.rb +65 -125
  98. data/spec/kitchen/provisioner/chef_base_spec.rb +798 -0
  99. data/spec/kitchen/provisioner/chef_solo_spec.rb +316 -0
  100. data/spec/kitchen/provisioner/chef_zero_spec.rb +624 -0
  101. data/spec/kitchen/provisioner/shell_spec.rb +269 -0
  102. data/spec/kitchen/provisioner_spec.rb +6 -6
  103. data/spec/kitchen/shell_out_spec.rb +143 -0
  104. data/spec/kitchen/ssh_spec.rb +683 -0
  105. data/spec/kitchen/state_file_spec.rb +28 -21
  106. data/spec/kitchen/suite_spec.rb +7 -7
  107. data/spec/kitchen/util_spec.rb +68 -10
  108. data/spec/kitchen_spec.rb +107 -0
  109. data/spec/spec_helper.rb +18 -13
  110. data/support/chef-client-zero.rb +10 -9
  111. data/support/chef_helpers.sh +16 -0
  112. data/support/download_helpers.sh +109 -0
  113. data/test-kitchen.gemspec +42 -33
  114. metadata +107 -33
@@ -16,7 +16,7 @@
16
16
  # See the License for the specific language governing permissions and
17
17
  # limitations under the License.
18
18
 
19
- require 'delegate'
19
+ require "delegate"
20
20
 
21
21
  module Kitchen
22
22
 
@@ -42,14 +42,14 @@ module Kitchen
42
42
  # @return [Kitchen::Config::Collection<Object>] a new collection of
43
43
  # matched objects
44
44
  def get_all(regexp)
45
- Kitchen::Collection.new(__getobj__.find_all { |i| i.name =~ regexp })
45
+ Kitchen::Collection.new(__getobj__.select { |i| i.name =~ regexp })
46
46
  end
47
47
 
48
48
  # Returns an Array of names from the collection as strings.
49
49
  #
50
50
  # @return [Array<String>] array of name strings
51
51
  def as_names
52
- __getobj__.map { |i| i.name }
52
+ __getobj__.map(&:name)
53
53
  end
54
54
  end
55
55
  end
@@ -33,10 +33,10 @@ module Kitchen
33
33
  :bright_cyan => 96, :bright_white => 97
34
34
  }.freeze
35
35
 
36
- COLORS = %w(
36
+ COLORS = %w[
37
37
  cyan yellow green magenta blue bright_cyan bright_yellow
38
38
  bright_green bright_magenta bright_blue
39
- ).freeze
39
+ ].freeze
40
40
 
41
41
  # Returns an ansi escaped string representing a color control sequence.
42
42
  #
@@ -46,8 +46,8 @@ module Kitchen
46
46
  # empty string otherwise
47
47
  def self.escape(name)
48
48
  return "" if name.nil?
49
- return "" unless ansi = ANSI[name]
50
- "\e[#{ansi}m"
49
+ return "" unless ANSI[name]
50
+ "\e[#{ANSI[name]}m"
51
51
  end
52
52
 
53
53
  # Returns a colorized ansi escaped string with the given color.
@@ -16,7 +16,7 @@
16
16
  # See the License for the specific language governing permissions and
17
17
  # limitations under the License.
18
18
 
19
- require 'thread'
19
+ require "thread"
20
20
 
21
21
  module Kitchen
22
22
 
@@ -29,27 +29,71 @@ module Kitchen
29
29
 
30
30
  include Logging
31
31
 
32
+ # Contstructs a new Command object.
33
+ #
34
+ # @param cmd_args [Array] remainder of the arguments from processed ARGV
35
+ # @param cmd_options [Hash] hash of Thor options
36
+ # @param options [Hash] configuration options
37
+ # @option options [String] :action action to take, usually corresponding
38
+ # to the subcommand name (default: `nil`)
39
+ # @option options [proc] :help a callable that displays help for the
40
+ # command
41
+ # @option options [Config] :config a Config object (default: `nil`)
42
+ # @option options [Loader] :loader a Loader object (default: `nil`)
43
+ # @option options [String] :shell a Thor shell object
32
44
  def initialize(cmd_args, cmd_options, options = {})
33
45
  @args = cmd_args
34
46
  @options = cmd_options
35
47
  @action = options.fetch(:action, nil)
36
- @help = options.fetch(:help, lambda { "No help provided" })
48
+ @help = options.fetch(:help, -> { "No help provided" })
37
49
  @config = options.fetch(:config, nil)
38
50
  @loader = options.fetch(:loader, nil)
39
51
  @shell = options.fetch(:shell)
40
52
  end
41
53
 
42
- protected
54
+ private
43
55
 
44
- attr_reader :args, :options, :help, :config, :shell, :action
56
+ # @return [Array] remainder of the arguments from processed ARGV
57
+ # @api private
58
+ attr_reader :args
45
59
 
60
+ # @return [Hash] hash of Thor options
61
+ # @api private
62
+ attr_reader :options
63
+
64
+ # @return [proc] a callable that displays help for the command
65
+ # @api private
66
+ attr_reader :help
67
+
68
+ # @return [Config] a Config object
69
+ # @api private
70
+ attr_reader :config
71
+
72
+ # @return [Thor::Shell] a Thor shell object
73
+ # @api private
74
+ attr_reader :shell
75
+
76
+ # @return [String] the action to perform
77
+ # @api private
78
+ attr_reader :action
79
+
80
+ # Emit an error message, display contextual help and then exit with a
81
+ # non-zero exit code.
82
+ #
83
+ # **Note** This method calls exit and will not return.
84
+ #
85
+ # @param msg [String] error message
86
+ # @api private
46
87
  def die(msg)
47
88
  error "\n#{msg}\n\n"
48
89
  help.call
49
90
  exit 1
50
91
  end
51
92
 
52
- def get_all_instances
93
+ # @return [Array<Instance>] an array of instances
94
+ # @raise [SystemExit] if no instances are returned
95
+ # @api private
96
+ def all_instances
53
97
  result = @config.instances
54
98
 
55
99
  if result.empty?
@@ -59,13 +103,20 @@ module Kitchen
59
103
  end
60
104
  end
61
105
 
62
- def get_filtered_instances(regexp)
106
+ # Return an array on instances whos name matches the regular expression.
107
+ #
108
+ # @param regexp [Regexp] a regular expression matching on instance names
109
+ # @return [Array<Instance>] an array of instances
110
+ # @raise [SystemExit] if no instances are returned or the regular
111
+ # expression is invalid
112
+ # @api private
113
+ def filtered_instances(regexp)
63
114
  result = begin
64
115
  @config.instances.get(regexp) ||
65
116
  @config.instances.get_all(/#{regexp}/)
66
117
  rescue RegexpError => e
67
- die "Invalid Ruby regular expression, " +
68
- "you may need to single quote the argument. " +
118
+ die "Invalid Ruby regular expression, " \
119
+ "you may need to single quote the argument. " \
69
120
  "Please try again or consult http://rubular.com/ (#{e.message})"
70
121
  end
71
122
  result = Array(result)
@@ -77,12 +128,21 @@ module Kitchen
77
128
  end
78
129
  end
79
130
 
131
+ # @return [Logger] the common logger
132
+ # @api private
80
133
  def logger
81
134
  Kitchen.logger
82
135
  end
83
136
 
137
+ # Return an array on instances whos name matches the regular expression,
138
+ # the full instance name, or the `"all"` literal.
139
+ #
140
+ # @param arg [String] an instance name, a regular expression, the literal
141
+ # `"all"`, or `nil`
142
+ # @return [Array<Instance>] an array of instances
143
+ # @api private
84
144
  def parse_subcommand(arg = nil)
85
- arg == "all" ? get_all_instances : get_filtered_instances(arg)
145
+ arg == "all" ? all_instances : filtered_instances(arg)
86
146
  end
87
147
  end
88
148
 
@@ -91,6 +151,13 @@ module Kitchen
91
151
  # @author Fletcher Nichol <fnichol@nichol.ca>
92
152
  module RunAction
93
153
 
154
+ # Run an instance action (create, converge, setup, verify, destroy) on
155
+ # a collection of instances. The instance actions will take place in a
156
+ # seperate thread of execution which may or may not be running
157
+ # concurrently.
158
+ #
159
+ # @param action [String] action to perform
160
+ # @param instances [Array<Instance>] an array of instances
94
161
  def run_action(action, instances, *args)
95
162
  concurrency = 1
96
163
  if options[:concurrency]
@@ -99,7 +166,7 @@ module Kitchen
99
166
  end
100
167
 
101
168
  queue = Queue.new
102
- instances.each {|i| queue << i }
169
+ instances.each { |i| queue << i }
103
170
  concurrency.times { queue << nil }
104
171
 
105
172
  threads = []
@@ -110,7 +177,7 @@ module Kitchen
110
177
  end
111
178
  end
112
179
  end
113
- threads.map { |i| i.join }
180
+ threads.map(&:join)
114
181
  end
115
182
  end
116
183
  end
@@ -16,9 +16,9 @@
16
16
  # See the License for the specific language governing permissions and
17
17
  # limitations under the License.
18
18
 
19
- require 'kitchen/command'
19
+ require "kitchen/command"
20
20
 
21
- require 'benchmark'
21
+ require "benchmark"
22
22
 
23
23
  module Kitchen
24
24
 
@@ -31,6 +31,7 @@ module Kitchen
31
31
 
32
32
  include RunAction
33
33
 
34
+ # Invoke the command.
34
35
  def call
35
36
  banner "Starting Kitchen (v#{Kitchen::VERSION})"
36
37
  elapsed = Benchmark.measure do
@@ -16,7 +16,7 @@
16
16
  # See the License for the specific language governing permissions and
17
17
  # limitations under the License.
18
18
 
19
- require 'kitchen/command'
19
+ require "kitchen/command"
20
20
 
21
21
  module Kitchen
22
22
 
@@ -27,20 +27,27 @@ module Kitchen
27
27
  # @author Fletcher Nichol <fnichol@nichol.ca>
28
28
  class Console < Kitchen::Command::Base
29
29
 
30
+ # Invoke the command.
30
31
  def call
31
- require 'pry'
32
+ require "pry"
32
33
  Pry.start(@config, :prompt => [prompt(">"), prompt("*")])
33
- rescue LoadError => e
34
+ rescue LoadError
34
35
  warn %{Make sure you have the pry gem installed. You can install it with:}
35
36
  warn %{`gem install pry` or including 'gem "pry"' in your Gemfile.}
36
37
  exit 1
37
38
  end
38
39
 
39
- protected
40
+ private
40
41
 
42
+ # Construct a custom Pry prompt proc.
43
+ #
44
+ # @param char [String] prompt character
45
+ # @return [proc] a prompt proc
46
+ # @api private
41
47
  def prompt(char)
42
48
  proc { |target_self, nest_level, pry|
43
- ["[#{pry.input_array.size}] ",
49
+ [
50
+ "[#{pry.input_array.size}] ",
44
51
  "kc(#{Pry.view_clip(target_self.class)})",
45
52
  "#{":#{nest_level}" unless nest_level.zero?}#{char} "
46
53
  ].join
@@ -16,10 +16,10 @@
16
16
  # See the License for the specific language governing permissions and
17
17
  # limitations under the License.
18
18
 
19
- require 'kitchen/command'
20
- require 'kitchen/diagnostic'
19
+ require "kitchen/command"
20
+ require "kitchen/diagnostic"
21
21
 
22
- require 'yaml'
22
+ require "yaml"
23
23
 
24
24
  module Kitchen
25
25
 
@@ -30,6 +30,7 @@ module Kitchen
30
30
  # @author Fletcher Nichol <fnichol@nichol.ca>
31
31
  class Diagnose < Kitchen::Command::Base
32
32
 
33
+ # Invoke the command.
33
34
  def call
34
35
  instances = record_failure { load_instances }
35
36
 
@@ -41,6 +42,10 @@ module Kitchen
41
42
 
42
43
  private
43
44
 
45
+ # Loads and returns instances if they are requested.
46
+ #
47
+ # @return [Array<Instance>] an array of instances or an empty array
48
+ # @api private
44
49
  def load_instances
45
50
  if options[:all] || options[:instances]
46
51
  parse_subcommand(args.first)
@@ -49,6 +54,10 @@ module Kitchen
49
54
  end
50
55
  end
51
56
 
57
+ # Loads and returns loader configuration if it is requested.
58
+ #
59
+ # @return [Hash,nil] a hash or nil
60
+ # @api private
52
61
  def load_loader
53
62
  if options[:all] || options[:loader]
54
63
  @loader
@@ -57,6 +66,11 @@ module Kitchen
57
66
  end
58
67
  end
59
68
 
69
+ # Returns a hash with exception detail if an exception is raised in the
70
+ # yielded block.
71
+ #
72
+ # @return [yield,Hash] the result of the yielded block or an error hash
73
+ # @api private
60
74
  def record_failure
61
75
  yield
62
76
  rescue => e
@@ -16,10 +16,9 @@
16
16
  # See the License for the specific language governing permissions and
17
17
  # limitations under the License.
18
18
 
19
- require 'kitchen/command'
19
+ require "kitchen/command"
20
20
 
21
- require 'rubygems/spec_fetcher'
22
- require 'safe_yaml'
21
+ require "rubygems/spec_fetcher"
23
22
 
24
23
  module Kitchen
25
24
 
@@ -30,6 +29,7 @@ module Kitchen
30
29
  # @author Fletcher Nichol <fnichol@nichol.ca>
31
30
  class DriverDiscover < Kitchen::Command::Base
32
31
 
32
+ # Invoke the command.
33
33
  def call
34
34
  specs = fetch_gem_specs.sort { |x, y| x[0] <=> y[0] }
35
35
  specs = specs[0, 49].push(["...", "..."]) if specs.size > 49
@@ -37,33 +37,52 @@ module Kitchen
37
37
  print_table(specs, :indent => 4)
38
38
  end
39
39
 
40
- protected
40
+ private
41
41
 
42
+ # Fetches Kitchen-related RubyGems and returns an array of name/version
43
+ # tuples.
44
+ #
45
+ # @return [Array<Array>] an array of name/version tuples
46
+ # @api private
42
47
  def fetch_gem_specs
43
- SafeYAML::OPTIONS[:suppress_warnings] = true
44
48
  req = Gem::Requirement.default
45
49
  dep = Gem::Deprecate.skip_during do
46
50
  Gem::Dependency.new(/kitchen-/i, req)
47
51
  end
48
52
  fetcher = Gem::SpecFetcher.fetcher
49
53
 
50
- specs = if fetcher.respond_to?(:find_matching)
54
+ if fetcher.respond_to?(:find_matching)
51
55
  fetch_gem_specs_pre_rubygems_2(fetcher, dep)
52
56
  else
53
57
  fetch_gem_specs_post_rubygems_2(fetcher, dep)
54
58
  end
55
59
  end
56
60
 
61
+ # Fetches gem specs for RubyGems 2 and later.
62
+ #
63
+ # @param fetcher [Gem::SpecFetcher] a gemspec fetcher
64
+ # @param dep [Gem::Dependency] a gem dependency object
65
+ # @return [Array<Array>] an array of name/version tuples
66
+ # @api private
57
67
  def fetch_gem_specs_post_rubygems_2(fetcher, dep)
58
68
  specs = fetcher.spec_for_dependency(dep, false)
59
69
  specs.first.map { |t| [t.first.name, t.first.version] }
60
70
  end
61
71
 
72
+ # Fetches gem specs for pre-RubyGems 2.
73
+ #
74
+ # @param fetcher [Gem::SpecFetcher] a gemspec fetcher
75
+ # @param dep [Gem::Dependency] a gem dependency object
76
+ # @return [Array<Array>] an array of name/version tuples
77
+ # @api private
62
78
  def fetch_gem_specs_pre_rubygems_2(fetcher, dep)
63
79
  specs = fetcher.find_matching(dep, false, false, false)
64
- specs.map { |t| t.first }.map { |t| t[0, 2] }
80
+ specs.map(&:first).map { |t| t[0, 2] }
65
81
  end
66
82
 
83
+ # Print out a display table.
84
+ #
85
+ # @api private
67
86
  def print_table(*args)
68
87
  shell.print_table(*args)
69
88
  end
@@ -0,0 +1,41 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: SAWANOBORI Yukihiko (<sawanoboriyu@higanworks.com>)
4
+ #
5
+ # Copyright (C) 2014, HiganWorks LLC
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require "kitchen/command"
20
+
21
+ module Kitchen
22
+
23
+ module Command
24
+
25
+ # Execute command on remote instance.
26
+ #
27
+ # @author SAWANOBORI Yukihiko (<sawanoboriyu@higanworks.com>)
28
+ class Exec < Kitchen::Command::Base
29
+
30
+ # Invoke the command.
31
+ def call
32
+ results = parse_subcommand(args.first)
33
+
34
+ results.each do |instance|
35
+ banner "Execute command on #{instance.name}."
36
+ instance.remote_exec(options[:command])
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -16,7 +16,7 @@
16
16
  # See the License for the specific language governing permissions and
17
17
  # limitations under the License.
18
18
 
19
- require 'kitchen/command'
19
+ require "kitchen/command"
20
20
 
21
21
  module Kitchen
22
22
 
@@ -27,24 +27,36 @@ module Kitchen
27
27
  # @author Fletcher Nichol <fnichol@nichol.ca>
28
28
  class List < Kitchen::Command::Base
29
29
 
30
+ # Invoke the command.
30
31
  def call
31
32
  result = parse_subcommand(args.first)
32
33
  if options[:debug]
33
- die "The --debug flag on the list subcommand is deprecated, " +
34
+ die "The --debug flag on the list subcommand is deprecated, " \
34
35
  "please use `kitchen diagnose'."
35
36
  elsif options[:bare]
36
- puts Array(result).map { |i| i.name }.join("\n")
37
+ puts Array(result).map(&:name).join("\n")
37
38
  else
38
39
  list_table(result)
39
40
  end
40
41
  end
41
42
 
42
- protected
43
+ private
43
44
 
45
+ # Add a trailing ansi color escape code to line up columns of colored
46
+ # output.
47
+ #
48
+ # @param string [String] a string
49
+ # @return [String]
50
+ # @api private
44
51
  def color_pad(string)
45
- string + set_color("", :white)
52
+ string + colorize("", :white)
46
53
  end
47
54
 
55
+ # Generate the display rows for an instance.
56
+ #
57
+ # @param instance [Instance] an instance
58
+ # @return [Array<String>]
59
+ # @api private
48
60
  def display_instance(instance)
49
61
  [
50
62
  color_pad(instance.name),
@@ -54,31 +66,49 @@ module Kitchen
54
66
  ]
55
67
  end
56
68
 
69
+ # Format and color the given last action.
70
+ #
71
+ # @param [String] the last action
72
+ # @return [String] formated last action
73
+ # @api private
57
74
  def format_last_action(last_action)
58
75
  case last_action
59
- when 'create' then set_color("Created", :cyan)
60
- when 'converge' then set_color("Converged", :magenta)
61
- when 'setup' then set_color("Set Up", :blue)
62
- when 'verify' then set_color("Verified", :yellow)
63
- when nil then set_color("<Not Created>", :red)
64
- else set_color("<Unknown>", :white)
76
+ when "create" then colorize("Created", :cyan)
77
+ when "converge" then colorize("Converged", :magenta)
78
+ when "setup" then colorize("Set Up", :blue)
79
+ when "verify" then colorize("Verified", :yellow)
80
+ when nil then colorize("<Not Created>", :red)
81
+ else colorize("<Unknown>", :white)
65
82
  end
66
83
  end
67
84
 
85
+ # Constructs a list display table and output it to the screen.
86
+ #
87
+ # @param result [Array<Instance>] an array of instances
88
+ # @api private
68
89
  def list_table(result)
69
90
  table = [
70
- [set_color("Instance", :green), set_color("Driver", :green),
71
- set_color("Provisioner", :green), set_color("Last Action", :green)]
91
+ [
92
+ colorize("Instance", :green), colorize("Driver", :green),
93
+ colorize("Provisioner", :green), colorize("Last Action", :green)
94
+ ]
72
95
  ]
73
96
  table += Array(result).map { |i| display_instance(i) }
74
97
  print_table(table)
75
98
  end
76
99
 
100
+ # Outputs a formatted display table.
101
+ #
102
+ # @api private
77
103
  def print_table(*args)
78
104
  shell.print_table(*args)
79
105
  end
80
106
 
81
- def set_color(*args)
107
+ # Colorize a string.
108
+ #
109
+ # @return [String] a colorized string
110
+ # @api private
111
+ def colorize(*args)
82
112
  shell.set_color(*args)
83
113
  end
84
114
  end