test-kitchen 1.7.0 → 1.7.1.dev

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.
Files changed (181) hide show
  1. checksums.yaml +4 -4
  2. data/.cane +8 -8
  3. data/.gitattributes +3 -0
  4. data/.github/ISSUE_TEMPLATE.md +55 -55
  5. data/.gitignore +28 -28
  6. data/.kitchen.ci.yml +23 -23
  7. data/.kitchen.proxy.yml +27 -27
  8. data/.rubocop.yml +3 -3
  9. data/.travis.yml +70 -70
  10. data/.yardopts +3 -3
  11. data/Berksfile +3 -3
  12. data/CHANGELOG.md +1090 -1083
  13. data/CONTRIBUTING.md +14 -14
  14. data/Gemfile +19 -19
  15. data/Gemfile.proxy_tests +4 -4
  16. data/Guardfile +42 -42
  17. data/LICENSE +15 -15
  18. data/MAINTAINERS.md +23 -23
  19. data/README.md +135 -135
  20. data/Rakefile +61 -61
  21. data/appveyor.yml +44 -44
  22. data/features/kitchen_action_commands.feature +164 -164
  23. data/features/kitchen_command.feature +16 -16
  24. data/features/kitchen_console_command.feature +34 -34
  25. data/features/kitchen_defaults.feature +38 -38
  26. data/features/kitchen_diagnose_command.feature +96 -96
  27. data/features/kitchen_driver_create_command.feature +64 -64
  28. data/features/kitchen_driver_discover_command.feature +25 -25
  29. data/features/kitchen_help_command.feature +16 -16
  30. data/features/kitchen_init_command.feature +274 -274
  31. data/features/kitchen_list_command.feature +104 -104
  32. data/features/kitchen_login_command.feature +62 -62
  33. data/features/kitchen_sink_command.feature +30 -30
  34. data/features/kitchen_test_command.feature +88 -88
  35. data/features/step_definitions/gem_steps.rb +36 -36
  36. data/features/step_definitions/git_steps.rb +5 -5
  37. data/features/step_definitions/output_steps.rb +5 -5
  38. data/features/support/env.rb +75 -75
  39. data/lib/kitchen.rb +150 -150
  40. data/lib/kitchen/base64_stream.rb +55 -55
  41. data/lib/kitchen/cli.rb +419 -419
  42. data/lib/kitchen/collection.rb +55 -55
  43. data/lib/kitchen/color.rb +65 -65
  44. data/lib/kitchen/command.rb +185 -185
  45. data/lib/kitchen/command/action.rb +45 -45
  46. data/lib/kitchen/command/console.rb +58 -58
  47. data/lib/kitchen/command/diagnose.rb +92 -92
  48. data/lib/kitchen/command/driver_discover.rb +105 -105
  49. data/lib/kitchen/command/exec.rb +41 -41
  50. data/lib/kitchen/command/list.rb +119 -119
  51. data/lib/kitchen/command/login.rb +43 -43
  52. data/lib/kitchen/command/sink.rb +54 -54
  53. data/lib/kitchen/command/test.rb +51 -51
  54. data/lib/kitchen/config.rb +322 -322
  55. data/lib/kitchen/configurable.rb +529 -529
  56. data/lib/kitchen/data_munger.rb +959 -959
  57. data/lib/kitchen/diagnostic.rb +141 -141
  58. data/lib/kitchen/driver.rb +56 -56
  59. data/lib/kitchen/driver/base.rb +134 -134
  60. data/lib/kitchen/driver/dummy.rb +108 -108
  61. data/lib/kitchen/driver/proxy.rb +72 -72
  62. data/lib/kitchen/driver/ssh_base.rb +357 -357
  63. data/lib/kitchen/errors.rb +229 -229
  64. data/lib/kitchen/generator/driver_create.rb +177 -177
  65. data/lib/kitchen/generator/init.rb +296 -296
  66. data/lib/kitchen/instance.rb +662 -662
  67. data/lib/kitchen/lazy_hash.rb +142 -142
  68. data/lib/kitchen/loader/yaml.rb +349 -349
  69. data/lib/kitchen/logger.rb +423 -423
  70. data/lib/kitchen/logging.rb +56 -56
  71. data/lib/kitchen/login_command.rb +52 -52
  72. data/lib/kitchen/metadata_chopper.rb +52 -52
  73. data/lib/kitchen/platform.rb +67 -67
  74. data/lib/kitchen/provisioner.rb +54 -54
  75. data/lib/kitchen/provisioner/base.rb +236 -236
  76. data/lib/kitchen/provisioner/chef/berkshelf.rb +114 -114
  77. data/lib/kitchen/provisioner/chef/common_sandbox.rb +322 -322
  78. data/lib/kitchen/provisioner/chef/librarian.rb +112 -112
  79. data/lib/kitchen/provisioner/chef_apply.rb +124 -124
  80. data/lib/kitchen/provisioner/chef_base.rb +341 -341
  81. data/lib/kitchen/provisioner/chef_solo.rb +88 -88
  82. data/lib/kitchen/provisioner/chef_zero.rb +245 -245
  83. data/lib/kitchen/provisioner/dummy.rb +79 -79
  84. data/lib/kitchen/provisioner/shell.rb +138 -138
  85. data/lib/kitchen/rake_tasks.rb +63 -63
  86. data/lib/kitchen/shell_out.rb +93 -93
  87. data/lib/kitchen/ssh.rb +276 -276
  88. data/lib/kitchen/state_file.rb +120 -120
  89. data/lib/kitchen/suite.rb +51 -51
  90. data/lib/kitchen/thor_tasks.rb +66 -66
  91. data/lib/kitchen/transport.rb +54 -54
  92. data/lib/kitchen/transport/base.rb +176 -176
  93. data/lib/kitchen/transport/dummy.rb +79 -79
  94. data/lib/kitchen/transport/ssh.rb +364 -364
  95. data/lib/kitchen/transport/winrm.rb +486 -486
  96. data/lib/kitchen/util.rb +147 -147
  97. data/lib/kitchen/verifier.rb +55 -55
  98. data/lib/kitchen/verifier/base.rb +235 -235
  99. data/lib/kitchen/verifier/busser.rb +277 -277
  100. data/lib/kitchen/verifier/dummy.rb +79 -79
  101. data/lib/kitchen/verifier/shell.rb +101 -101
  102. data/lib/kitchen/version.rb +21 -21
  103. data/lib/vendor/hash_recursive_merge.rb +82 -82
  104. data/spec/kitchen/base64_stream_spec.rb +77 -77
  105. data/spec/kitchen/cli_spec.rb +56 -56
  106. data/spec/kitchen/collection_spec.rb +80 -80
  107. data/spec/kitchen/color_spec.rb +54 -54
  108. data/spec/kitchen/config_spec.rb +408 -408
  109. data/spec/kitchen/configurable_spec.rb +1095 -1095
  110. data/spec/kitchen/data_munger_spec.rb +2694 -2694
  111. data/spec/kitchen/diagnostic_spec.rb +129 -129
  112. data/spec/kitchen/driver/base_spec.rb +121 -121
  113. data/spec/kitchen/driver/dummy_spec.rb +199 -199
  114. data/spec/kitchen/driver/proxy_spec.rb +138 -138
  115. data/spec/kitchen/driver/ssh_base_spec.rb +1115 -1115
  116. data/spec/kitchen/driver_spec.rb +112 -112
  117. data/spec/kitchen/errors_spec.rb +309 -309
  118. data/spec/kitchen/instance_spec.rb +1419 -1419
  119. data/spec/kitchen/lazy_hash_spec.rb +117 -117
  120. data/spec/kitchen/loader/yaml_spec.rb +774 -774
  121. data/spec/kitchen/logger_spec.rb +429 -429
  122. data/spec/kitchen/logging_spec.rb +59 -59
  123. data/spec/kitchen/login_command_spec.rb +68 -68
  124. data/spec/kitchen/metadata_chopper_spec.rb +82 -82
  125. data/spec/kitchen/platform_spec.rb +89 -89
  126. data/spec/kitchen/provisioner/base_spec.rb +386 -386
  127. data/spec/kitchen/provisioner/chef_apply_spec.rb +136 -136
  128. data/spec/kitchen/provisioner/chef_base_spec.rb +1161 -1161
  129. data/spec/kitchen/provisioner/chef_solo_spec.rb +557 -557
  130. data/spec/kitchen/provisioner/chef_zero_spec.rb +1001 -1001
  131. data/spec/kitchen/provisioner/dummy_spec.rb +99 -99
  132. data/spec/kitchen/provisioner/shell_spec.rb +566 -566
  133. data/spec/kitchen/provisioner_spec.rb +107 -107
  134. data/spec/kitchen/shell_out_spec.rb +150 -150
  135. data/spec/kitchen/ssh_spec.rb +693 -693
  136. data/spec/kitchen/state_file_spec.rb +129 -129
  137. data/spec/kitchen/suite_spec.rb +62 -62
  138. data/spec/kitchen/transport/base_spec.rb +89 -89
  139. data/spec/kitchen/transport/ssh_spec.rb +1255 -1255
  140. data/spec/kitchen/transport/winrm_spec.rb +1143 -1143
  141. data/spec/kitchen/transport_spec.rb +112 -112
  142. data/spec/kitchen/util_spec.rb +165 -165
  143. data/spec/kitchen/verifier/base_spec.rb +362 -362
  144. data/spec/kitchen/verifier/busser_spec.rb +610 -610
  145. data/spec/kitchen/verifier/dummy_spec.rb +99 -99
  146. data/spec/kitchen/verifier/shell_spec.rb +160 -160
  147. data/spec/kitchen/verifier_spec.rb +120 -120
  148. data/spec/kitchen_spec.rb +114 -114
  149. data/spec/spec_helper.rb +85 -85
  150. data/spec/support/powershell_max_size_spec.rb +40 -40
  151. data/support/busser_install_command.ps1 +14 -14
  152. data/support/busser_install_command.sh +14 -14
  153. data/support/chef-client-zero.rb +77 -77
  154. data/support/chef_base_init_command.ps1 +18 -18
  155. data/support/chef_base_init_command.sh +2 -2
  156. data/support/chef_base_install_command.ps1 +85 -85
  157. data/support/chef_base_install_command.sh +229 -229
  158. data/support/chef_zero_prepare_command_legacy.ps1 +9 -9
  159. data/support/chef_zero_prepare_command_legacy.sh +10 -10
  160. data/support/download_helpers.sh +109 -109
  161. data/support/dummy-validation.pem +27 -27
  162. data/templates/driver/CHANGELOG.md.erb +3 -3
  163. data/templates/driver/Gemfile.erb +3 -3
  164. data/templates/driver/README.md.erb +64 -64
  165. data/templates/driver/Rakefile.erb +21 -21
  166. data/templates/driver/driver.rb.erb +23 -23
  167. data/templates/driver/gemspec.erb +29 -29
  168. data/templates/driver/gitignore.erb +17 -17
  169. data/templates/driver/license_apachev2.erb +15 -15
  170. data/templates/driver/license_lgplv3.erb +16 -16
  171. data/templates/driver/license_mit.erb +22 -22
  172. data/templates/driver/license_reserved.erb +5 -5
  173. data/templates/driver/tailor.erb +4 -4
  174. data/templates/driver/travis.yml.erb +11 -11
  175. data/templates/driver/version.rb.erb +12 -12
  176. data/templates/init/chefignore.erb +1 -1
  177. data/templates/init/kitchen.yml.erb +18 -18
  178. data/test-kitchen.gemspec +62 -62
  179. data/test/integration/default/default_spec.rb +3 -3
  180. data/testing_windows.md +37 -37
  181. metadata +5 -4
@@ -1,177 +1,177 @@
1
- # -*- encoding: utf-8 -*-
2
- #
3
- # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
- #
5
- # Copyright (C) 2013, Fletcher Nichol
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 "thor/group"
20
- require "thor/util"
21
-
22
- module Kitchen
23
-
24
- module Generator
25
-
26
- # A generator to create a new Kitchen Driver gem project.
27
- #
28
- # @author Fletcher Nichol <fnichol@nichol.ca>
29
- class DriverCreate < Thor::Group
30
-
31
- include Thor::Actions
32
-
33
- argument :name, :type => :string
34
-
35
- class_option :license,
36
- :aliases => "-l",
37
- :default => "apachev2",
38
- :desc => "License type for gem (apachev2, mit, lgplv3, reserved)"
39
-
40
- # Invoke the command.
41
- def create
42
- self.class.source_root(Kitchen.source_root.join("templates", "driver"))
43
-
44
- create_core_files
45
- create_source_files
46
- initialize_git
47
- end
48
-
49
- private
50
-
51
- # Creates top-level project files.
52
- #
53
- # @api private
54
- def create_core_files
55
- empty_directory(target_dir)
56
-
57
- create_template("CHANGELOG.md.erb", "CHANGELOG.md")
58
- create_template("Gemfile.erb", "Gemfile")
59
- create_template("Rakefile.erb", "Rakefile")
60
- create_template("README.md.erb", "README.md")
61
- create_template("gemspec.erb", "#{config[:gem_name]}.gemspec")
62
- create_template("license_#{config[:license]}.erb", license_filename)
63
- create_template("gitignore.erb", ".gitignore")
64
- create_template("tailor.erb", ".tailor")
65
- create_template("travis.yml.erb", ".travis.yml")
66
- create_file(File.join(target_dir, ".cane"))
67
- end
68
-
69
- # Creates source code files.
70
- #
71
- # @api private
72
- def create_source_files
73
- empty_directory(File.join(target_dir, "lib/kitchen/driver"))
74
-
75
- create_template(
76
- "version.rb.erb",
77
- "lib/kitchen/driver/#{name}_version.rb"
78
- )
79
- create_template(
80
- "driver.rb.erb",
81
- "lib/kitchen/driver/#{name}.rb"
82
- )
83
- end
84
-
85
- # Initialize a git repository.
86
- #
87
- # @api private
88
- def initialize_git
89
- inside(target_dir) do
90
- run("git init", :capture => true)
91
- run("git add .", :capture => true)
92
- end
93
- end
94
-
95
- # Render an ERb template to a destination file.
96
- #
97
- # @param erb [String] path to an ERb file
98
- # @param dest [String] destination path for the rendered template
99
- # @api private
100
- def create_template(erb, dest)
101
- template(erb, File.join(target_dir, dest), config)
102
- end
103
-
104
- # @return [String] the path to the gem skeleton project
105
- # @api private
106
- def target_dir
107
- File.join(Dir.pwd, "kitchen-#{name}")
108
- end
109
-
110
- # @return [Hash] a configuration hash which can be used by templates as
111
- # context
112
- # @api private
113
- def config
114
- @config ||= {
115
- :name => name,
116
- :gem_name => "kitchen-#{name}",
117
- :gemspec => "kitchen-#{name}.gemspec",
118
- :klass_name => ::Thor::Util.camel_case(name),
119
- :constant_name => ::Thor::Util.snake_case(name).upcase,
120
- :author => author,
121
- :email => email,
122
- :license => options[:license],
123
- :license_string => license_string,
124
- :year => Time.now.year
125
- }
126
- end
127
-
128
- # @return [String] a default author name taken from git configuration if
129
- # found
130
- # @api private
131
- def author
132
- git_user_name = `git config user.name`.chomp
133
- git_user_name.empty? ? "TODO: Write your name" : git_user_name
134
- end
135
-
136
- # @return [String] a default email address taken from git configuration
137
- # if found
138
- # @api private
139
- def email
140
- git_user_email = `git config user.email`.chomp
141
- git_user_email.empty? ? "TODO: Write your email" : git_user_email
142
- end
143
-
144
- # @return [String] a rendered license string for a given license
145
- # @api private
146
- def license_string
147
- case options[:license]
148
- when "mit" then "MIT"
149
- when "apachev2" then "Apache 2.0"
150
- when "lgplv3" then "LGPL 3.0"
151
- when "reserved" then "All rights reserved"
152
- else
153
- raise ArgumentError, "No such license #{options[:license]}"
154
- end
155
- end
156
-
157
- # @return [String] the filename to use for the license file
158
- # @api private
159
- def license_filename
160
- case options[:license]
161
- when "mit" then "LICENSE.txt"
162
- when "apachev2", "reserved" then "LICENSE"
163
- when "lgplv3" then "COPYING"
164
- else
165
- raise ArgumentError, "No such license #{options[:license]}"
166
- end
167
- end
168
-
169
- # @return [String] the license comment/preamble
170
- # @api private
171
- def license_comment
172
- @license_comment ||= IO.read(File.join(target_dir, license_filename)).
173
- gsub(/^/, "# ").gsub(/\s+$/, "")
174
- end
175
- end
176
- end
177
- end
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2013, Fletcher Nichol
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 "thor/group"
20
+ require "thor/util"
21
+
22
+ module Kitchen
23
+
24
+ module Generator
25
+
26
+ # A generator to create a new Kitchen Driver gem project.
27
+ #
28
+ # @author Fletcher Nichol <fnichol@nichol.ca>
29
+ class DriverCreate < Thor::Group
30
+
31
+ include Thor::Actions
32
+
33
+ argument :name, :type => :string
34
+
35
+ class_option :license,
36
+ :aliases => "-l",
37
+ :default => "apachev2",
38
+ :desc => "License type for gem (apachev2, mit, lgplv3, reserved)"
39
+
40
+ # Invoke the command.
41
+ def create
42
+ self.class.source_root(Kitchen.source_root.join("templates", "driver"))
43
+
44
+ create_core_files
45
+ create_source_files
46
+ initialize_git
47
+ end
48
+
49
+ private
50
+
51
+ # Creates top-level project files.
52
+ #
53
+ # @api private
54
+ def create_core_files
55
+ empty_directory(target_dir)
56
+
57
+ create_template("CHANGELOG.md.erb", "CHANGELOG.md")
58
+ create_template("Gemfile.erb", "Gemfile")
59
+ create_template("Rakefile.erb", "Rakefile")
60
+ create_template("README.md.erb", "README.md")
61
+ create_template("gemspec.erb", "#{config[:gem_name]}.gemspec")
62
+ create_template("license_#{config[:license]}.erb", license_filename)
63
+ create_template("gitignore.erb", ".gitignore")
64
+ create_template("tailor.erb", ".tailor")
65
+ create_template("travis.yml.erb", ".travis.yml")
66
+ create_file(File.join(target_dir, ".cane"))
67
+ end
68
+
69
+ # Creates source code files.
70
+ #
71
+ # @api private
72
+ def create_source_files
73
+ empty_directory(File.join(target_dir, "lib/kitchen/driver"))
74
+
75
+ create_template(
76
+ "version.rb.erb",
77
+ "lib/kitchen/driver/#{name}_version.rb"
78
+ )
79
+ create_template(
80
+ "driver.rb.erb",
81
+ "lib/kitchen/driver/#{name}.rb"
82
+ )
83
+ end
84
+
85
+ # Initialize a git repository.
86
+ #
87
+ # @api private
88
+ def initialize_git
89
+ inside(target_dir) do
90
+ run("git init", :capture => true)
91
+ run("git add .", :capture => true)
92
+ end
93
+ end
94
+
95
+ # Render an ERb template to a destination file.
96
+ #
97
+ # @param erb [String] path to an ERb file
98
+ # @param dest [String] destination path for the rendered template
99
+ # @api private
100
+ def create_template(erb, dest)
101
+ template(erb, File.join(target_dir, dest), config)
102
+ end
103
+
104
+ # @return [String] the path to the gem skeleton project
105
+ # @api private
106
+ def target_dir
107
+ File.join(Dir.pwd, "kitchen-#{name}")
108
+ end
109
+
110
+ # @return [Hash] a configuration hash which can be used by templates as
111
+ # context
112
+ # @api private
113
+ def config
114
+ @config ||= {
115
+ :name => name,
116
+ :gem_name => "kitchen-#{name}",
117
+ :gemspec => "kitchen-#{name}.gemspec",
118
+ :klass_name => ::Thor::Util.camel_case(name),
119
+ :constant_name => ::Thor::Util.snake_case(name).upcase,
120
+ :author => author,
121
+ :email => email,
122
+ :license => options[:license],
123
+ :license_string => license_string,
124
+ :year => Time.now.year
125
+ }
126
+ end
127
+
128
+ # @return [String] a default author name taken from git configuration if
129
+ # found
130
+ # @api private
131
+ def author
132
+ git_user_name = `git config user.name`.chomp
133
+ git_user_name.empty? ? "TODO: Write your name" : git_user_name
134
+ end
135
+
136
+ # @return [String] a default email address taken from git configuration
137
+ # if found
138
+ # @api private
139
+ def email
140
+ git_user_email = `git config user.email`.chomp
141
+ git_user_email.empty? ? "TODO: Write your email" : git_user_email
142
+ end
143
+
144
+ # @return [String] a rendered license string for a given license
145
+ # @api private
146
+ def license_string
147
+ case options[:license]
148
+ when "mit" then "MIT"
149
+ when "apachev2" then "Apache 2.0"
150
+ when "lgplv3" then "LGPL 3.0"
151
+ when "reserved" then "All rights reserved"
152
+ else
153
+ raise ArgumentError, "No such license #{options[:license]}"
154
+ end
155
+ end
156
+
157
+ # @return [String] the filename to use for the license file
158
+ # @api private
159
+ def license_filename
160
+ case options[:license]
161
+ when "mit" then "LICENSE.txt"
162
+ when "apachev2", "reserved" then "LICENSE"
163
+ when "lgplv3" then "COPYING"
164
+ else
165
+ raise ArgumentError, "No such license #{options[:license]}"
166
+ end
167
+ end
168
+
169
+ # @return [String] the license comment/preamble
170
+ # @api private
171
+ def license_comment
172
+ @license_comment ||= IO.read(File.join(target_dir, license_filename)).
173
+ gsub(/^/, "# ").gsub(/\s+$/, "")
174
+ end
175
+ end
176
+ end
177
+ end
@@ -1,296 +1,296 @@
1
- # -*- encoding: utf-8 -*-
2
- #
3
- # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
- #
5
- # Copyright (C) 2013, Fletcher Nichol
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 "rubygems/gem_runner"
20
- require "thor/group"
21
-
22
- module Kitchen
23
-
24
- module Generator
25
-
26
- # A project initialization generator, to help prepare a cookbook project
27
- # for testing with Kitchen.
28
- #
29
- # @author Fletcher Nichol <fnichol@nichol.ca>
30
- class Init < Thor::Group
31
-
32
- include Thor::Actions
33
-
34
- class_option :driver,
35
- :type => :array,
36
- :aliases => "-D",
37
- :default => "kitchen-vagrant",
38
- :desc => <<-D.gsub(/^\s+/, "").gsub(/\n/, " ")
39
- One or more Kitchen Driver gems to be installed or added to a
40
- Gemfile
41
- D
42
-
43
- class_option :provisioner,
44
- :type => :string,
45
- :aliases => "-P",
46
- :default => "chef_solo",
47
- :desc => <<-D.gsub(/^\s+/, "").gsub(/\n/, " ")
48
- The default Kitchen Provisioner to use
49
- D
50
-
51
- class_option :create_gemfile,
52
- :type => :boolean,
53
- :default => false,
54
- :desc => <<-D.gsub(/^\s+/, "").gsub(/\n/, " ")
55
- Whether or not to create a Gemfile if one does not exist.
56
- Default: false
57
- D
58
-
59
- # Invoke the command.
60
- def init
61
- self.class.source_root(Kitchen.source_root.join("templates", "init"))
62
-
63
- create_kitchen_yaml
64
- create_chefignore
65
- prepare_rakefile
66
- prepare_thorfile
67
- create_test_dir
68
- prepare_gitignore
69
- prepare_gemfile
70
- add_drivers
71
- display_bundle_message
72
- end
73
-
74
- private
75
-
76
- # Creates the `.kitchen.yml` file.
77
- #
78
- # @api private
79
- def create_kitchen_yaml
80
- cookbook_name = if File.exist?(File.expand_path("metadata.rb"))
81
- MetadataChopper.extract("metadata.rb").first
82
- else
83
- nil
84
- end
85
- run_list = cookbook_name ? "recipe[#{cookbook_name}::default]" : nil
86
- driver_plugin = Array(options[:driver]).first || "dummy"
87
-
88
- template("kitchen.yml.erb", ".kitchen.yml",
89
- :driver_plugin => driver_plugin.sub(/^kitchen-/, ""),
90
- :provisioner => options[:provisioner],
91
- :run_list => Array(run_list)
92
- )
93
- end
94
-
95
- # Creates the `chefignore` file.
96
- #
97
- # @api private
98
- def create_chefignore
99
- template("chefignore.erb", "chefignore")
100
- end
101
-
102
- # @return [true,false] whether or not a Gemfile needs to be initialized
103
- # @api private
104
- def init_gemfile?
105
- File.exist?(File.join(destination_root, "Gemfile")) ||
106
- options[:create_gemfile]
107
- end
108
-
109
- # @return [true,false] whether or not a Rakefile needs to be initialized
110
- # @api private
111
- def init_rakefile?
112
- File.exist?(File.join(destination_root, "Rakefile")) &&
113
- not_in_file?("Rakefile", %r{require 'kitchen/rake_tasks'})
114
- end
115
-
116
- # @return [true,false] whether or not a Thorfile needs to be initialized
117
- # @api private
118
- def init_thorfile?
119
- File.exist?(File.join(destination_root, "Thorfile")) &&
120
- not_in_file?("Thorfile", %r{require 'kitchen/thor_tasks'})
121
- end
122
-
123
- # @return [true,false] whether or not a test directory needs to be
124
- # initialized
125
- # @api private
126
- def init_test_dir?
127
- Dir.glob("test/integration/*").select { |d| File.directory?(d) }.empty?
128
- end
129
-
130
- # @return [true,false] whether or not a `.gitignore` file needs to be
131
- # initialized
132
- # @api private
133
- def init_git?
134
- File.directory?(File.join(destination_root, ".git"))
135
- end
136
-
137
- # Prepares a Rakefile.
138
- #
139
- # @api private
140
- def prepare_rakefile
141
- return unless init_rakefile?
142
-
143
- rakedoc = <<-RAKE.gsub(/^ {10}/, "")
144
-
145
- begin
146
- require 'kitchen/rake_tasks'
147
- Kitchen::RakeTasks.new
148
- rescue LoadError
149
- puts '>>>>> Kitchen gem not loaded, omitting tasks' unless ENV['CI']
150
- end
151
- RAKE
152
- append_to_file(File.join(destination_root, "Rakefile"), rakedoc)
153
- end
154
-
155
- # Prepares a Thorfile.
156
- #
157
- # @api private
158
- def prepare_thorfile
159
- return unless init_thorfile?
160
-
161
- thordoc = <<-THOR.gsub(/^ {10}/, "")
162
-
163
- begin
164
- require 'kitchen/thor_tasks'
165
- Kitchen::ThorTasks.new
166
- rescue LoadError
167
- puts '>>>>> Kitchen gem not loaded, omitting tasks' unless ENV['CI']
168
- end
169
- THOR
170
- append_to_file(File.join(destination_root, "Thorfile"), thordoc)
171
- end
172
-
173
- # Create the default test directory
174
- #
175
- # @api private
176
- def create_test_dir
177
- empty_directory "test/integration/default" if init_test_dir?
178
- end
179
-
180
- # Prepares the .gitignore file
181
- #
182
- # @api private
183
- def prepare_gitignore
184
- return unless init_git?
185
-
186
- append_to_gitignore(".kitchen/")
187
- append_to_gitignore(".kitchen.local.yml")
188
- end
189
-
190
- # Appends a line to the .gitignore file.
191
- #
192
- # @api private
193
- def append_to_gitignore(line)
194
- create_file(".gitignore") unless File.exist?(File.join(destination_root, ".gitignore"))
195
-
196
- if IO.readlines(File.join(destination_root, ".gitignore")).grep(%r{^#{line}}).empty?
197
- append_to_file(".gitignore", "#{line}\n")
198
- end
199
- end
200
-
201
- # Prepares a Gemfile.
202
- #
203
- # @api private
204
- def prepare_gemfile
205
- return unless init_gemfile?
206
-
207
- create_gemfile_if_missing
208
- add_gem_to_gemfile
209
- end
210
-
211
- # Creates a Gemfile if missing
212
- #
213
- # @api private
214
- def create_gemfile_if_missing
215
- unless File.exist?(File.join(destination_root, "Gemfile"))
216
- create_file("Gemfile", %{source "https://rubygems.org"\n\n})
217
- end
218
- end
219
-
220
- # Appends entries to a Gemfile.
221
- #
222
- # @api private
223
- def add_gem_to_gemfile
224
- if not_in_file?("Gemfile", %r{gem ('|")test-kitchen('|")})
225
- append_to_file("Gemfile", %{gem "test-kitchen"\n})
226
- @display_bundle_msg = true
227
- end
228
- end
229
-
230
- # Appends driver gems to a Gemfile or installs them.
231
- #
232
- # @api private
233
- def add_drivers
234
- return if options[:driver].nil? || options[:driver].empty?
235
-
236
- Array(options[:driver]).each do |driver_gem|
237
- if File.exist?(File.join(destination_root, "Gemfile")) || options[:create_gemfile]
238
- add_driver_to_gemfile(driver_gem)
239
- else
240
- install_gem(driver_gem)
241
- end
242
- end
243
- end
244
-
245
- # Appends a driver gem to a Gemfile.
246
- #
247
- # @api private
248
- def add_driver_to_gemfile(driver_gem)
249
- if not_in_file?("Gemfile", %r{gem ('|")#{driver_gem}('|")})
250
- append_to_file("Gemfile", %{gem "#{driver_gem}"\n})
251
- @display_bundle_msg = true
252
- end
253
- end
254
-
255
- # Installs a driver gem.
256
- #
257
- # @api private
258
- def install_gem(driver_gem)
259
- unbundlerize { Gem::GemRunner.new.run(["install", driver_gem]) }
260
- rescue Gem::SystemExitException => e
261
- raise unless e.exit_code == 0
262
- end
263
-
264
- # Displays a bundle warning message to the user.
265
- #
266
- # @api private
267
- def display_bundle_message
268
- if @display_bundle_msg
269
- say "You must run `bundle install' to fetch any new gems.", :red
270
- end
271
- end
272
-
273
- # Determines whether or not a pattern is found in a file.
274
- #
275
- # @param filename [String] filename to read
276
- # @param regexp [Regexp] a regular expression
277
- # @return [true,false] whether or not a pattern is found in a file
278
- # @api private
279
- def not_in_file?(filename, regexp)
280
- IO.readlines(File.join(destination_root, filename)).grep(regexp).empty?
281
- end
282
-
283
- # Save off any Bundler/Ruby-related environment variables so that the
284
- # yielded block can run "bundler-free" (and restore at the end).
285
- #
286
- # @api private
287
- def unbundlerize
288
- keys = ENV.keys.select { |key| key =~ /^BUNDLER?_/ } + %w[RUBYOPT]
289
-
290
- keys.each { |key| ENV["__#{key}"] = ENV[key]; ENV.delete(key) }
291
- yield
292
- keys.each { |key| ENV[key] = ENV.delete("__#{key}") }
293
- end
294
- end
295
- end
296
- end
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2013, Fletcher Nichol
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 "rubygems/gem_runner"
20
+ require "thor/group"
21
+
22
+ module Kitchen
23
+
24
+ module Generator
25
+
26
+ # A project initialization generator, to help prepare a cookbook project
27
+ # for testing with Kitchen.
28
+ #
29
+ # @author Fletcher Nichol <fnichol@nichol.ca>
30
+ class Init < Thor::Group
31
+
32
+ include Thor::Actions
33
+
34
+ class_option :driver,
35
+ :type => :array,
36
+ :aliases => "-D",
37
+ :default => "kitchen-vagrant",
38
+ :desc => <<-D.gsub(/^\s+/, "").gsub(/\n/, " ")
39
+ One or more Kitchen Driver gems to be installed or added to a
40
+ Gemfile
41
+ D
42
+
43
+ class_option :provisioner,
44
+ :type => :string,
45
+ :aliases => "-P",
46
+ :default => "chef_solo",
47
+ :desc => <<-D.gsub(/^\s+/, "").gsub(/\n/, " ")
48
+ The default Kitchen Provisioner to use
49
+ D
50
+
51
+ class_option :create_gemfile,
52
+ :type => :boolean,
53
+ :default => false,
54
+ :desc => <<-D.gsub(/^\s+/, "").gsub(/\n/, " ")
55
+ Whether or not to create a Gemfile if one does not exist.
56
+ Default: false
57
+ D
58
+
59
+ # Invoke the command.
60
+ def init
61
+ self.class.source_root(Kitchen.source_root.join("templates", "init"))
62
+
63
+ create_kitchen_yaml
64
+ create_chefignore
65
+ prepare_rakefile
66
+ prepare_thorfile
67
+ create_test_dir
68
+ prepare_gitignore
69
+ prepare_gemfile
70
+ add_drivers
71
+ display_bundle_message
72
+ end
73
+
74
+ private
75
+
76
+ # Creates the `.kitchen.yml` file.
77
+ #
78
+ # @api private
79
+ def create_kitchen_yaml
80
+ cookbook_name = if File.exist?(File.expand_path("metadata.rb"))
81
+ MetadataChopper.extract("metadata.rb").first
82
+ else
83
+ nil
84
+ end
85
+ run_list = cookbook_name ? "recipe[#{cookbook_name}::default]" : nil
86
+ driver_plugin = Array(options[:driver]).first || "dummy"
87
+
88
+ template("kitchen.yml.erb", ".kitchen.yml",
89
+ :driver_plugin => driver_plugin.sub(/^kitchen-/, ""),
90
+ :provisioner => options[:provisioner],
91
+ :run_list => Array(run_list)
92
+ )
93
+ end
94
+
95
+ # Creates the `chefignore` file.
96
+ #
97
+ # @api private
98
+ def create_chefignore
99
+ template("chefignore.erb", "chefignore")
100
+ end
101
+
102
+ # @return [true,false] whether or not a Gemfile needs to be initialized
103
+ # @api private
104
+ def init_gemfile?
105
+ File.exist?(File.join(destination_root, "Gemfile")) ||
106
+ options[:create_gemfile]
107
+ end
108
+
109
+ # @return [true,false] whether or not a Rakefile needs to be initialized
110
+ # @api private
111
+ def init_rakefile?
112
+ File.exist?(File.join(destination_root, "Rakefile")) &&
113
+ not_in_file?("Rakefile", %r{require 'kitchen/rake_tasks'})
114
+ end
115
+
116
+ # @return [true,false] whether or not a Thorfile needs to be initialized
117
+ # @api private
118
+ def init_thorfile?
119
+ File.exist?(File.join(destination_root, "Thorfile")) &&
120
+ not_in_file?("Thorfile", %r{require 'kitchen/thor_tasks'})
121
+ end
122
+
123
+ # @return [true,false] whether or not a test directory needs to be
124
+ # initialized
125
+ # @api private
126
+ def init_test_dir?
127
+ Dir.glob("test/integration/*").select { |d| File.directory?(d) }.empty?
128
+ end
129
+
130
+ # @return [true,false] whether or not a `.gitignore` file needs to be
131
+ # initialized
132
+ # @api private
133
+ def init_git?
134
+ File.directory?(File.join(destination_root, ".git"))
135
+ end
136
+
137
+ # Prepares a Rakefile.
138
+ #
139
+ # @api private
140
+ def prepare_rakefile
141
+ return unless init_rakefile?
142
+
143
+ rakedoc = <<-RAKE.gsub(/^ {10}/, "")
144
+
145
+ begin
146
+ require 'kitchen/rake_tasks'
147
+ Kitchen::RakeTasks.new
148
+ rescue LoadError
149
+ puts '>>>>> Kitchen gem not loaded, omitting tasks' unless ENV['CI']
150
+ end
151
+ RAKE
152
+ append_to_file(File.join(destination_root, "Rakefile"), rakedoc)
153
+ end
154
+
155
+ # Prepares a Thorfile.
156
+ #
157
+ # @api private
158
+ def prepare_thorfile
159
+ return unless init_thorfile?
160
+
161
+ thordoc = <<-THOR.gsub(/^ {10}/, "")
162
+
163
+ begin
164
+ require 'kitchen/thor_tasks'
165
+ Kitchen::ThorTasks.new
166
+ rescue LoadError
167
+ puts '>>>>> Kitchen gem not loaded, omitting tasks' unless ENV['CI']
168
+ end
169
+ THOR
170
+ append_to_file(File.join(destination_root, "Thorfile"), thordoc)
171
+ end
172
+
173
+ # Create the default test directory
174
+ #
175
+ # @api private
176
+ def create_test_dir
177
+ empty_directory "test/integration/default" if init_test_dir?
178
+ end
179
+
180
+ # Prepares the .gitignore file
181
+ #
182
+ # @api private
183
+ def prepare_gitignore
184
+ return unless init_git?
185
+
186
+ append_to_gitignore(".kitchen/")
187
+ append_to_gitignore(".kitchen.local.yml")
188
+ end
189
+
190
+ # Appends a line to the .gitignore file.
191
+ #
192
+ # @api private
193
+ def append_to_gitignore(line)
194
+ create_file(".gitignore") unless File.exist?(File.join(destination_root, ".gitignore"))
195
+
196
+ if IO.readlines(File.join(destination_root, ".gitignore")).grep(%r{^#{line}}).empty?
197
+ append_to_file(".gitignore", "#{line}\n")
198
+ end
199
+ end
200
+
201
+ # Prepares a Gemfile.
202
+ #
203
+ # @api private
204
+ def prepare_gemfile
205
+ return unless init_gemfile?
206
+
207
+ create_gemfile_if_missing
208
+ add_gem_to_gemfile
209
+ end
210
+
211
+ # Creates a Gemfile if missing
212
+ #
213
+ # @api private
214
+ def create_gemfile_if_missing
215
+ unless File.exist?(File.join(destination_root, "Gemfile"))
216
+ create_file("Gemfile", %{source "https://rubygems.org"\n\n})
217
+ end
218
+ end
219
+
220
+ # Appends entries to a Gemfile.
221
+ #
222
+ # @api private
223
+ def add_gem_to_gemfile
224
+ if not_in_file?("Gemfile", %r{gem ('|")test-kitchen('|")})
225
+ append_to_file("Gemfile", %{gem "test-kitchen"\n})
226
+ @display_bundle_msg = true
227
+ end
228
+ end
229
+
230
+ # Appends driver gems to a Gemfile or installs them.
231
+ #
232
+ # @api private
233
+ def add_drivers
234
+ return if options[:driver].nil? || options[:driver].empty?
235
+
236
+ Array(options[:driver]).each do |driver_gem|
237
+ if File.exist?(File.join(destination_root, "Gemfile")) || options[:create_gemfile]
238
+ add_driver_to_gemfile(driver_gem)
239
+ else
240
+ install_gem(driver_gem)
241
+ end
242
+ end
243
+ end
244
+
245
+ # Appends a driver gem to a Gemfile.
246
+ #
247
+ # @api private
248
+ def add_driver_to_gemfile(driver_gem)
249
+ if not_in_file?("Gemfile", %r{gem ('|")#{driver_gem}('|")})
250
+ append_to_file("Gemfile", %{gem "#{driver_gem}"\n})
251
+ @display_bundle_msg = true
252
+ end
253
+ end
254
+
255
+ # Installs a driver gem.
256
+ #
257
+ # @api private
258
+ def install_gem(driver_gem)
259
+ unbundlerize { Gem::GemRunner.new.run(["install", driver_gem]) }
260
+ rescue Gem::SystemExitException => e
261
+ raise unless e.exit_code == 0
262
+ end
263
+
264
+ # Displays a bundle warning message to the user.
265
+ #
266
+ # @api private
267
+ def display_bundle_message
268
+ if @display_bundle_msg
269
+ say "You must run `bundle install' to fetch any new gems.", :red
270
+ end
271
+ end
272
+
273
+ # Determines whether or not a pattern is found in a file.
274
+ #
275
+ # @param filename [String] filename to read
276
+ # @param regexp [Regexp] a regular expression
277
+ # @return [true,false] whether or not a pattern is found in a file
278
+ # @api private
279
+ def not_in_file?(filename, regexp)
280
+ IO.readlines(File.join(destination_root, filename)).grep(regexp).empty?
281
+ end
282
+
283
+ # Save off any Bundler/Ruby-related environment variables so that the
284
+ # yielded block can run "bundler-free" (and restore at the end).
285
+ #
286
+ # @api private
287
+ def unbundlerize
288
+ keys = ENV.keys.select { |key| key =~ /^BUNDLER?_/ } + %w[RUBYOPT]
289
+
290
+ keys.each { |key| ENV["__#{key}"] = ENV[key]; ENV.delete(key) }
291
+ yield
292
+ keys.each { |key| ENV[key] = ENV.delete("__#{key}") }
293
+ end
294
+ end
295
+ end
296
+ end