chef-dk 0.2.0

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 (142) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.md +192 -0
  3. data/LICENSE +201 -0
  4. data/README.md +198 -0
  5. data/Rakefile +18 -0
  6. data/bin/chef +25 -0
  7. data/lib/chef-dk.rb +19 -0
  8. data/lib/chef-dk/builtin_commands.rb +31 -0
  9. data/lib/chef-dk/chef_runner.rb +83 -0
  10. data/lib/chef-dk/cli.rb +135 -0
  11. data/lib/chef-dk/command/base.rb +71 -0
  12. data/lib/chef-dk/command/exec.rb +33 -0
  13. data/lib/chef-dk/command/gem.rb +47 -0
  14. data/lib/chef-dk/command/generate.rb +97 -0
  15. data/lib/chef-dk/command/generator_commands.rb +417 -0
  16. data/lib/chef-dk/command/shell_init.rb +80 -0
  17. data/lib/chef-dk/command/verify.rb +226 -0
  18. data/lib/chef-dk/commands_map.rb +115 -0
  19. data/lib/chef-dk/component_test.rb +142 -0
  20. data/lib/chef-dk/cookbook_metadata.rb +36 -0
  21. data/lib/chef-dk/cookbook_omnifetch.rb +29 -0
  22. data/lib/chef-dk/cookbook_profiler/git.rb +95 -0
  23. data/lib/chef-dk/cookbook_profiler/identifiers.rb +79 -0
  24. data/lib/chef-dk/cookbook_profiler/null_scm.rb +32 -0
  25. data/lib/chef-dk/exceptions.rb +46 -0
  26. data/lib/chef-dk/generator.rb +70 -0
  27. data/lib/chef-dk/helpers.rb +95 -0
  28. data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +46 -0
  29. data/lib/chef-dk/policyfile/community_cookbook_source.rb +84 -0
  30. data/lib/chef-dk/policyfile/cookbook_sources.rb +20 -0
  31. data/lib/chef-dk/policyfile/cookbook_spec.rb +96 -0
  32. data/lib/chef-dk/policyfile/dsl.rb +148 -0
  33. data/lib/chef-dk/policyfile/null_cookbook_source.rb +37 -0
  34. data/lib/chef-dk/policyfile_compiler.rb +217 -0
  35. data/lib/chef-dk/policyfile_lock.rb +243 -0
  36. data/lib/chef-dk/shell_out.rb +36 -0
  37. data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +3 -0
  38. data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +96 -0
  39. data/lib/chef-dk/skeletons/code_generator/files/default/converge_spec.rb +9 -0
  40. data/lib/chef-dk/skeletons/code_generator/files/default/gitignore +16 -0
  41. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper.rb +8 -0
  42. data/lib/chef-dk/skeletons/code_generator/metadata.rb +8 -0
  43. data/lib/chef-dk/skeletons/code_generator/recipes/app.rb +65 -0
  44. data/lib/chef-dk/skeletons/code_generator/recipes/attribute.rb +12 -0
  45. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +50 -0
  46. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook_file.rb +24 -0
  47. data/lib/chef-dk/skeletons/code_generator/recipes/lwrp.rb +23 -0
  48. data/lib/chef-dk/skeletons/code_generator/recipes/recipe.rb +9 -0
  49. data/lib/chef-dk/skeletons/code_generator/recipes/template.rb +32 -0
  50. data/lib/chef-dk/skeletons/code_generator/templates/default/README.md.erb +4 -0
  51. data/lib/chef-dk/skeletons/code_generator/templates/default/attribute.rb.erb +0 -0
  52. data/lib/chef-dk/skeletons/code_generator/templates/default/cookbook_file.erb +0 -0
  53. data/lib/chef-dk/skeletons/code_generator/templates/default/default_recipe.rb.erb +8 -0
  54. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen.yml.erb +16 -0
  55. data/lib/chef-dk/skeletons/code_generator/templates/default/metadata.rb.erb +8 -0
  56. data/lib/chef-dk/skeletons/code_generator/templates/default/provider.rb.erb +0 -0
  57. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe.rb.erb +0 -0
  58. data/lib/chef-dk/skeletons/code_generator/templates/default/resource.rb.erb +0 -0
  59. data/lib/chef-dk/skeletons/code_generator/templates/default/template.erb +0 -0
  60. data/lib/chef-dk/version.rb +20 -0
  61. data/spec/shared/setup_git_cookbooks.rb +53 -0
  62. data/spec/spec_helper.rb +32 -0
  63. data/spec/test_helpers.rb +59 -0
  64. data/spec/unit/chef_runner_spec.rb +70 -0
  65. data/spec/unit/cli_spec.rb +151 -0
  66. data/spec/unit/command/base_spec.rb +88 -0
  67. data/spec/unit/command/exec_spec.rb +123 -0
  68. data/spec/unit/command/generate_spec.rb +102 -0
  69. data/spec/unit/command/generator_commands_spec.rb +504 -0
  70. data/spec/unit/command/shell_init_spec.rb +109 -0
  71. data/spec/unit/command/verify_spec.rb +311 -0
  72. data/spec/unit/commands_map_spec.rb +57 -0
  73. data/spec/unit/component_test_spec.rb +126 -0
  74. data/spec/unit/cookbook_metadata_spec.rb +62 -0
  75. data/spec/unit/cookbook_profiler/git_spec.rb +127 -0
  76. data/spec/unit/cookbook_profiler/identifiers_spec.rb +79 -0
  77. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_one.rb +9 -0
  78. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_two.rb +9 -0
  79. data/spec/unit/fixtures/command/cli_test_command.rb +26 -0
  80. data/spec/unit/fixtures/command/explicit_path_example.rb +7 -0
  81. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -0
  82. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +3 -0
  83. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -0
  84. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/chefignore +96 -0
  85. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -0
  86. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -0
  87. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/.kitchen.yml +16 -0
  88. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +3 -0
  89. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/README.md +4 -0
  90. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/chefignore +96 -0
  91. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/metadata.rb +8 -0
  92. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/recipes/default.rb +8 -0
  93. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/.kitchen.yml +16 -0
  94. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +3 -0
  95. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/README.md +4 -0
  96. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/chefignore +96 -0
  97. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/metadata.rb +8 -0
  98. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/recipes/default.rb +8 -0
  99. data/spec/unit/fixtures/cookbooks_api/pruned_small_universe.json +1322 -0
  100. data/spec/unit/fixtures/cookbooks_api/small_universe.json +2987 -0
  101. data/spec/unit/fixtures/cookbooks_api/universe.json +1 -0
  102. data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +36 -0
  103. data/spec/unit/fixtures/dev_cookbooks/README.md +16 -0
  104. data/spec/unit/fixtures/dev_cookbooks/bar-cookbook.gitbundle +0 -0
  105. data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/bin/.keep +0 -0
  106. data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/embedded/.keep +0 -0
  107. data/spec/unit/fixtures/eg_omnibus_dir/missing_apps/embedded/bin/.keep +0 -0
  108. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/bin/.keep +0 -0
  109. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/apps/berkshelf/.keep +0 -0
  110. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/apps/test-kitchen/.keep +0 -0
  111. data/spec/unit/fixtures/eg_omnibus_dir/missing_component/embedded/bin/.keep +0 -0
  112. data/spec/unit/fixtures/eg_omnibus_dir/valid/bin/.keep +0 -0
  113. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/integration_test +2 -0
  114. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/verify_me +5 -0
  115. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef-dk/.keep +0 -0
  116. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef/verify_me +3 -0
  117. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/test-kitchen/verify_me +2 -0
  118. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/bin/.keep +0 -0
  119. data/spec/unit/fixtures/example_app/Policyfile.rb +0 -0
  120. data/spec/unit/fixtures/example_cookbook/.gitignore +17 -0
  121. data/spec/unit/fixtures/example_cookbook/.kitchen.yml +16 -0
  122. data/spec/unit/fixtures/example_cookbook/Berksfile +3 -0
  123. data/spec/unit/fixtures/example_cookbook/README.md +4 -0
  124. data/spec/unit/fixtures/example_cookbook/chefignore +96 -0
  125. data/spec/unit/fixtures/example_cookbook/metadata.rb +8 -0
  126. data/spec/unit/fixtures/example_cookbook/recipes/default.rb +8 -0
  127. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/.kitchen.yml +16 -0
  128. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +3 -0
  129. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/README.md +4 -0
  130. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/chefignore +96 -0
  131. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/metadata.rb +8 -0
  132. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/recipes/default.rb +8 -0
  133. data/spec/unit/fixtures/local_path_cookbooks/metadata-missing/README.md +2 -0
  134. data/spec/unit/policyfile/chef_server_cookbook_source_spec.rb +34 -0
  135. data/spec/unit/policyfile/community_cookbook_source_spec.rb +51 -0
  136. data/spec/unit/policyfile/cookbook_spec_spec.rb +200 -0
  137. data/spec/unit/policyfile/null_cookbook_source_spec.rb +35 -0
  138. data/spec/unit/policyfile_builder_spec.rb +489 -0
  139. data/spec/unit/policyfile_demands_spec.rb +484 -0
  140. data/spec/unit/policyfile_evaluation_spec.rb +284 -0
  141. data/spec/unit/shell_out_spec.rb +34 -0
  142. metadata +422 -0
@@ -0,0 +1,97 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2014 Chef Software Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'chef-dk/command/base'
19
+ require 'chef-dk/command/generator_commands'
20
+
21
+ module ChefDK
22
+ module Command
23
+ class Generate < Base
24
+
25
+ GeneratorCommand = Struct.new(:name, :class_name, :description)
26
+
27
+ def self.generators
28
+ @generators ||= []
29
+ end
30
+
31
+ def self.generator(name, class_name, description)
32
+ generators << GeneratorCommand.new(name, class_name, description)
33
+ end
34
+
35
+ generator(:app, :App, "Generate an application repo")
36
+ generator(:cookbook, :Cookbook, "Generate a single cookbook")
37
+ generator(:recipe, :Recipe, "Generate a new recipe")
38
+ generator(:attribute, :Attribute, "Generate an attributes file")
39
+ generator(:template, :Template, "Generate a file template")
40
+ generator(:file, :CookbookFile, "Generate a cookbook file")
41
+ generator(:lwrp, :LWRP, "Generate a lightweight resource/provider")
42
+
43
+ def self.banner_headline
44
+ <<-E
45
+ Usage: chef generate GENERATOR [options]
46
+
47
+ Available generators:
48
+ E
49
+ end
50
+
51
+ def self.generator_list
52
+ justify_size = generators.map {|g| g.name.size }.max + 2
53
+ generators.map {|g| " #{g.name.to_s.ljust(justify_size)}#{g.description}"}.join("\n")
54
+ end
55
+
56
+ def self.banner
57
+ banner_headline + generator_list + "\n"
58
+ end
59
+
60
+ # chef generate app path/to/basename --skel=path/to/skeleton --example
61
+ # chef generate file name [path/to/cookbook_root] (inferred from cwd) --from=source_file
62
+
63
+ def initialize(*args)
64
+ super
65
+ end
66
+
67
+ def run(params)
68
+ if generator_spec = generator_for(params[0])
69
+ params.shift
70
+ generator = GeneratorCommands.build(generator_spec.class_name, params)
71
+ generator.run
72
+ else
73
+ msg(banner)
74
+ 1
75
+ end
76
+ end
77
+
78
+ def generator_for(arg)
79
+ self.class.generators.find {|g| g.name.to_s == arg}
80
+ end
81
+
82
+ # In the Base class, this is defined to be true if any args match "-h" or
83
+ # "--help". Here we override that behavior such that if the first
84
+ # argument is a valid generator name, like `chef generate cookbook -h`,
85
+ # we delegate the request to the specified generator.
86
+ def needs_help?(params)
87
+ return false if have_generator?(params[0])
88
+ super
89
+ end
90
+
91
+ def have_generator?(name)
92
+ self.class.generators.map {|g| g.name.to_s}.include?(name)
93
+ end
94
+
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,417 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2014 Chef Software Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'mixlib/cli'
19
+ require 'rbconfig'
20
+ require 'pathname'
21
+ require 'chef-dk/command/base'
22
+ require 'chef-dk/chef_runner'
23
+ require 'chef-dk/generator'
24
+
25
+ module ChefDK
26
+ module Command
27
+
28
+ # ## SharedGeneratorOptions
29
+ #
30
+ # These CLI options are shared amongst the generator commands
31
+ module SharedGeneratorOptions
32
+ include Mixlib::CLI
33
+
34
+ option :generator_cookbook,
35
+ :short => "-g GENERATOR_COOKBOOK_PATH",
36
+ :long => "--generator-cookbook GENERATOR_COOKBOOK_PATH",
37
+ :description => "Use GENERATOR_COOKBOOK_PATH for the code_generator cookbook",
38
+ :default => File.expand_path("../../skeletons", __FILE__),
39
+ :proc => Proc.new { |s| File.expand_path(s) },
40
+ :on => :tail
41
+ end
42
+
43
+ # ## GeneratorCommands
44
+ #
45
+ # This module is the namespace for all subcommands of `chef generate`
46
+ module GeneratorCommands
47
+
48
+ def self.build(class_name, params)
49
+ const_get(class_name).new(params)
50
+ end
51
+
52
+ # ## Base
53
+ #
54
+ # Base class for `chef generate` subcommands. Contains basic behaviors
55
+ # for setting up the generator context, detecting git, and launching a
56
+ # chef converge.
57
+ #
58
+ # The behavior of the generators is largely delegated to a chef cookbook.
59
+ # The default implementation is the `code_generator` cookbook in
60
+ # chef-dk/skeletons/code_generator.
61
+ class Base < Command::Base
62
+
63
+ attr_reader :params
64
+
65
+ options.merge!(SharedGeneratorOptions.options)
66
+
67
+ def initialize(params)
68
+ super()
69
+ @params = params
70
+ end
71
+
72
+ # An instance of ChefRunner. Calling ChefRunner#converge will trigger
73
+ # convergence and generate the desired code.
74
+ def chef_runner
75
+ @chef_runner ||= ChefRunner.new(generator_cookbook_path, ["code_generator::#{recipe}"])
76
+ end
77
+
78
+ # Path to the directory where the code_generator cookbook is located.
79
+ # For now, this is hard coded to the 'skeletons' directory in this
80
+ # repo.
81
+ def generator_cookbook_path
82
+ config[:generator_cookbook]
83
+ end
84
+
85
+ # Sets git related generator_context values.
86
+ def setup_context
87
+ Generator.context.have_git = have_git?
88
+ Generator.context.skip_git_init = false
89
+ end
90
+
91
+ # Delegates to `Generator.context`, the singleton instance of
92
+ # Generator::Context
93
+ def generator_context
94
+ Generator.context
95
+ end
96
+
97
+ # Checks the `PATH` for the presence of a `git` (or `git.exe`, on
98
+ # windows) executable.
99
+ def have_git?
100
+ path = ENV["PATH"] || ""
101
+ paths = path.split(File::PATH_SEPARATOR)
102
+ paths.any? {|bin_path| File.exist?(File.join(bin_path, "git#{RbConfig::CONFIG['EXEEXT']}"))}
103
+ end
104
+
105
+ end
106
+
107
+ # ## App
108
+ # chef generate app path/to/basename --generator-cookbook=path/to/generator
109
+ #
110
+ # Generates a full "application" directory structure.
111
+ class App < Base
112
+
113
+ banner "Usage: chef generate app NAME [options]"
114
+
115
+ attr_reader :errors
116
+ attr_reader :app_name_or_path
117
+
118
+ options.merge!(SharedGeneratorOptions.options)
119
+
120
+ def initialize(params)
121
+ @params_valid = true
122
+ @app_name = nil
123
+ super
124
+ end
125
+
126
+ def run
127
+ read_and_validate_params
128
+ if params_valid?
129
+ setup_context
130
+ chef_runner.converge
131
+ else
132
+ msg(banner)
133
+ 1
134
+ end
135
+ end
136
+
137
+ def setup_context
138
+ super
139
+ generator_context.app_root = app_root
140
+ generator_context.app_name = app_name
141
+ generator_context.cookbook_root ||= cookbook_root
142
+ generator_context.cookbook_name ||= cookbook_name
143
+ end
144
+
145
+ def recipe
146
+ "app"
147
+ end
148
+
149
+ def app_name
150
+ File.basename(app_full_path)
151
+ end
152
+
153
+ def app_root
154
+ File.dirname(app_full_path)
155
+ end
156
+
157
+ def cookbook_root
158
+ File.join(app_full_path, 'cookbooks')
159
+ end
160
+
161
+ def cookbook_name
162
+ app_name
163
+ end
164
+
165
+ def app_full_path
166
+ File.expand_path(app_name_or_path, Dir.pwd)
167
+ end
168
+
169
+ def read_and_validate_params
170
+ arguments = parse_options(params)
171
+ @app_name_or_path = arguments[0]
172
+ @params_valid = false unless @app_name_or_path
173
+ end
174
+
175
+ def params_valid?
176
+ @params_valid
177
+ end
178
+
179
+ end
180
+
181
+ # ## CookbookFile
182
+ # chef generate cookbook path/to/basename --generator-cookbook=path/to/generator
183
+ #
184
+ # Generates a basic cookbook directory structure. Most file types are
185
+ # omitted, the user is expected to add additional files as needed using
186
+ # the relevant generators.
187
+ class Cookbook < Base
188
+
189
+ banner "Usage: chef generate cookbook NAME [options]"
190
+
191
+ attr_reader :errors
192
+
193
+ attr_reader :cookbook_name_or_path
194
+
195
+ options.merge!(SharedGeneratorOptions.options)
196
+
197
+ def initialize(params)
198
+ @params_valid = true
199
+ @cookbook_name = nil
200
+ super
201
+ end
202
+
203
+ def run
204
+ read_and_validate_params
205
+ if params_valid?
206
+ setup_context
207
+ chef_runner.converge
208
+ else
209
+ msg(banner)
210
+ 1
211
+ end
212
+ end
213
+
214
+ def setup_context
215
+ super
216
+ generator_context.skip_git_init = cookbook_path_in_git_repo?
217
+ generator_context.cookbook_root = cookbook_root
218
+ generator_context.cookbook_name = cookbook_name
219
+ end
220
+
221
+ def recipe
222
+ "cookbook"
223
+ end
224
+
225
+ def cookbook_name
226
+ File.basename(cookbook_full_path)
227
+ end
228
+
229
+ def cookbook_root
230
+ File.dirname(cookbook_full_path)
231
+ end
232
+
233
+ def cookbook_full_path
234
+ File.expand_path(cookbook_name_or_path, Dir.pwd)
235
+ end
236
+
237
+ def read_and_validate_params
238
+ arguments = parse_options(params)
239
+ @cookbook_name_or_path = arguments[0]
240
+ @params_valid = false unless @cookbook_name_or_path
241
+ end
242
+
243
+ def params_valid?
244
+ @params_valid
245
+ end
246
+
247
+ def cookbook_path_in_git_repo?
248
+ Pathname.new(cookbook_full_path).ascend do |dir|
249
+ return true if File.directory?(File.join(dir.to_s, ".git"))
250
+ end
251
+ false
252
+ end
253
+
254
+ end
255
+
256
+ # ## CookbookCodeFile
257
+ # A base class for generators that add individual files to existing
258
+ # cookbooks.
259
+ class CookbookCodeFile < Base
260
+
261
+ attr_reader :errors
262
+ attr_reader :cookbook_path
263
+ attr_reader :new_file_basename
264
+
265
+ options.merge!(SharedGeneratorOptions.options)
266
+
267
+ def initialize(params)
268
+ @params_valid = true
269
+ @cookbook_full_path = nil
270
+ @new_file_basename = nil
271
+ @errors = []
272
+ super
273
+ end
274
+
275
+ def run
276
+ read_and_validate_params
277
+ if params_valid?
278
+ setup_context
279
+ chef_runner.converge
280
+ else
281
+ errors.each {|error| err("Error: #{error}") }
282
+ parse_options
283
+ msg(opt_parser)
284
+ 1
285
+ end
286
+ end
287
+
288
+ def setup_context
289
+ super
290
+ generator_context.cookbook_root = cookbook_root
291
+ generator_context.cookbook_name = cookbook_name
292
+ generator_context.new_file_basename = new_file_basename
293
+ end
294
+
295
+ def cookbook_root
296
+ File.dirname(cookbook_path)
297
+ end
298
+
299
+ def cookbook_name
300
+ File.basename(cookbook_path)
301
+ end
302
+
303
+ def read_and_validate_params
304
+ arguments = parse_options(params)
305
+ case arguments.size
306
+ when 1
307
+ @new_file_basename = arguments[0]
308
+ @cookbook_path = Dir.pwd
309
+ validate_cookbook_path
310
+ when 2
311
+ @cookbook_path = arguments[0]
312
+ @new_file_basename = arguments[1]
313
+ else
314
+ @params_valid = false
315
+ end
316
+ end
317
+
318
+ def validate_cookbook_path
319
+ unless File.directory?(File.join(cookbook_path, "recipes"))
320
+ @errors << "Directory #{cookbook_path} is not a cookbook"
321
+ @params_valid = false
322
+ end
323
+ end
324
+
325
+ def params_valid?
326
+ @params_valid
327
+ end
328
+ end
329
+
330
+ # chef generate recipe [path/to/cookbook/root] name
331
+ class Recipe < CookbookCodeFile
332
+
333
+ banner "Usage: chef generate recipe [path/to/cookbook] NAME [options]"
334
+
335
+ options.merge!(SharedGeneratorOptions.options)
336
+
337
+ def recipe
338
+ 'recipe'
339
+ end
340
+
341
+ end
342
+
343
+ # chef generate attribute [path/to/cookbook_root] NAME
344
+ class Attribute < CookbookCodeFile
345
+
346
+ banner "Usage: chef generate attribute [path/to/cookbook] NAME [options]"
347
+
348
+ options.merge!(SharedGeneratorOptions.options)
349
+
350
+ def recipe
351
+ 'attribute'
352
+ end
353
+
354
+ end
355
+
356
+ # chef generate lwrp [path/to/cookbook_root] NAME
357
+ class LWRP < CookbookCodeFile
358
+
359
+ banner "Usage: chef generate lwrp [path/to/cookbook] NAME [options]"
360
+
361
+ options.merge!(SharedGeneratorOptions.options)
362
+
363
+ def recipe
364
+ 'lwrp'
365
+ end
366
+
367
+ end
368
+
369
+ # chef generate template [path/to/cookbook_root] name --source=source_file
370
+ class Template < CookbookCodeFile
371
+
372
+ option :source,
373
+ :short => "-s SOURCE_FILE",
374
+ :long => "--source SOURCE_FILE",
375
+ :description => "Copy content from SOURCE_FILE"
376
+
377
+ banner "Usage: chef generate template [path/to/cookbook] NAME [options]"
378
+
379
+ options.merge!(SharedGeneratorOptions.options)
380
+
381
+ def recipe
382
+ 'template'
383
+ end
384
+
385
+ def setup_context
386
+ super
387
+ generator_context.content_source = config[:source]
388
+ end
389
+
390
+ end
391
+
392
+ # chef generate file [path/to/cookbook_root] name --source=source_file
393
+ class CookbookFile < CookbookCodeFile
394
+ option :source,
395
+ :short => "-s SOURCE_FILE",
396
+ :long => "--source SOURCE_FILE",
397
+ :description => "Copy content from SOURCE_FILE"
398
+
399
+ banner "Usage: chef generate file [path/to/cookbook] NAME [options]"
400
+
401
+ options.merge!(SharedGeneratorOptions.options)
402
+
403
+ def recipe
404
+ 'cookbook_file'
405
+ end
406
+
407
+ def setup_context
408
+ super
409
+ generator_context.content_source = config[:source]
410
+ end
411
+ end
412
+
413
+ end
414
+
415
+
416
+ end
417
+ end