chef-gen-flavors 0.8.6 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +5 -0
  3. data/LICENSE +2 -0
  4. data/Manifest.txt +0 -37
  5. data/README.md +113 -330
  6. data/chef-gen-flavors.gemspec +9 -9
  7. data/lib/chef_gen/flavors.rb +34 -100
  8. metadata +16 -47
  9. data/lib/chef_gen/flavor_base.rb +0 -266
  10. data/lib/chef_gen/snippet/attributes.rb +0 -35
  11. data/lib/chef_gen/snippet/chef_spec.rb +0 -111
  12. data/lib/chef_gen/snippet/cookbook_base.rb +0 -160
  13. data/lib/chef_gen/snippet/example_file.rb +0 -38
  14. data/lib/chef_gen/snippet/example_template.rb +0 -40
  15. data/lib/chef_gen/snippet/git_init.rb +0 -21
  16. data/lib/chef_gen/snippet/recipes.rb +0 -37
  17. data/lib/chef_gen/snippet/resource_provider.rb +0 -42
  18. data/lib/chef_gen/snippet/standard_ignore.rb +0 -73
  19. data/lib/chef_gen/snippet/style_foodcritic.rb +0 -51
  20. data/lib/chef_gen/snippet/style_rubocop.rb +0 -94
  21. data/lib/chef_gen/snippet/style_tailor.rb +0 -48
  22. data/lib/chef_gen/snippet/test_kitchen.rb +0 -109
  23. data/lib/chef_gen/snippets.rb +0 -18
  24. data/shared/snippet/attributes/attributes_default_rb.erb +0 -8
  25. data/shared/snippet/chef_spec/_rspec.erb +0 -2
  26. data/shared/snippet/chef_spec/spec_chef_runner_context_rb.erb +0 -36
  27. data/shared/snippet/chef_spec/spec_recipes_default_spec_rb.erb +0 -7
  28. data/shared/snippet/chef_spec/spec_spec_helper_rb.erb +0 -95
  29. data/shared/snippet/cookbookbase/Berksfile.erb +0 -12
  30. data/shared/snippet/cookbookbase/CHANGELOG_md.erb +0 -5
  31. data/shared/snippet/cookbookbase/Gemfile.erb +0 -18
  32. data/shared/snippet/cookbookbase/Guardfile.erb +0 -16
  33. data/shared/snippet/cookbookbase/README_md.erb +0 -92
  34. data/shared/snippet/cookbookbase/Rakefile.erb +0 -20
  35. data/shared/snippet/cookbookbase/metadata_rb.erb +0 -10
  36. data/shared/snippet/examplefile/files_default_example_conf +0 -34
  37. data/shared/snippet/exampletemplate/templates_default_example_conf_erb +0 -22
  38. data/shared/snippet/recipes/recipes_default_rb.erb +0 -9
  39. data/shared/snippet/resourceprovider/providers_default_rb.erb +0 -20
  40. data/shared/snippet/resourceprovider/resources_default_rb.erb +0 -9
  41. data/shared/snippet/stylerubocop/_rubocop_yml.erb +0 -31
  42. data/shared/snippet/testkitchen/_kitchen_yml.erb +0 -30
  43. data/shared/snippet/testkitchen/libraries_kitchen_helper_rb +0 -13
  44. data/shared/snippet/testkitchen/test_integration_default_serverspec_recipes_default_spec_rb.erb +0 -16
  45. data/shared/snippet/testkitchen/test_integration_default_serverspec_spec_helper_rb.erb +0 -7
@@ -1,19 +1,19 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: chef-gen-flavors 0.8.6.20150806075045 ruby lib
2
+ # stub: chef-gen-flavors 0.9.0.20150904171033 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "chef-gen-flavors"
6
- s.version = "0.8.6.20150806075045"
6
+ s.version = "0.9.0.20150904171033"
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib"]
10
10
  s.authors = ["James FitzGibbon"]
11
- s.date = "2015-08-06"
11
+ s.date = "2015-09-05"
12
12
  s.description = "chef-gen-flavors is a framework for creating custom templates for the\n'chef generate' command provided by ChefDK.\n\nThis gem simply provides a framework; templates are provided by separate\ngems, which you can host privately for use within your organization or\npublicly for the Chef community to use.\n\nAt present this is focused primarily on providing templates for generation of\ncookbooks, as this is where most organization-specific customization takes place.\nSupport for the other artifacts that ChefDK can generate may work, but is not\nthe focus of early releases."
13
- s.email = ["james.i.fitzgibbon@nordstrom.com"]
13
+ s.email = ["james@nadt.net"]
14
14
  s.extra_rdoc_files = ["ARUBA_STEPS.md", "History.md", "Manifest.txt", "README.md"]
15
- s.files = ["ARUBA_STEPS.md", "History.md", "LICENSE", "Manifest.txt", "README.md", "chef-gen-flavors.gemspec", "lib/chef_gen/flavor.rb", "lib/chef_gen/flavor_base.rb", "lib/chef_gen/flavors.rb", "lib/chef_gen/flavors/cucumber.rb", "lib/chef_gen/flavors/cucumber/bundle.rb", "lib/chef_gen/flavors/cucumber/chefdk.rb", "lib/chef_gen/flavors/cucumber/kitchen.rb", "lib/chef_gen/flavors/cucumber/knife.rb", "lib/chef_gen/flavors/cucumber/rake.rb", "lib/chef_gen/flavors/cucumber/regex.rb", "lib/chef_gen/snippet/attributes.rb", "lib/chef_gen/snippet/chef_spec.rb", "lib/chef_gen/snippet/cookbook_base.rb", "lib/chef_gen/snippet/example_file.rb", "lib/chef_gen/snippet/example_template.rb", "lib/chef_gen/snippet/git_init.rb", "lib/chef_gen/snippet/recipes.rb", "lib/chef_gen/snippet/resource_provider.rb", "lib/chef_gen/snippet/standard_ignore.rb", "lib/chef_gen/snippet/style_foodcritic.rb", "lib/chef_gen/snippet/style_rubocop.rb", "lib/chef_gen/snippet/style_tailor.rb", "lib/chef_gen/snippet/test_kitchen.rb", "lib/chef_gen/snippets.rb", "shared/snippet/attributes/attributes_default_rb.erb", "shared/snippet/chef_spec/_rspec.erb", "shared/snippet/chef_spec/spec_chef_runner_context_rb.erb", "shared/snippet/chef_spec/spec_recipes_default_spec_rb.erb", "shared/snippet/chef_spec/spec_spec_helper_rb.erb", "shared/snippet/cookbookbase/Berksfile.erb", "shared/snippet/cookbookbase/CHANGELOG_md.erb", "shared/snippet/cookbookbase/Gemfile.erb", "shared/snippet/cookbookbase/Guardfile.erb", "shared/snippet/cookbookbase/README_md.erb", "shared/snippet/cookbookbase/Rakefile.erb", "shared/snippet/cookbookbase/metadata_rb.erb", "shared/snippet/examplefile/files_default_example_conf", "shared/snippet/exampletemplate/templates_default_example_conf_erb", "shared/snippet/recipes/recipes_default_rb.erb", "shared/snippet/resourceprovider/providers_default_rb.erb", "shared/snippet/resourceprovider/resources_default_rb.erb", "shared/snippet/stylerubocop/_rubocop_yml.erb", "shared/snippet/testkitchen/_kitchen_yml.erb", "shared/snippet/testkitchen/libraries_kitchen_helper_rb", "shared/snippet/testkitchen/test_integration_default_serverspec_recipes_default_spec_rb.erb", "shared/snippet/testkitchen/test_integration_default_serverspec_spec_helper_rb.erb"]
16
- s.homepage = "https://github.com/Nordstrom/chef-gen-flavors"
15
+ s.files = ["ARUBA_STEPS.md", "History.md", "LICENSE", "Manifest.txt", "README.md", "chef-gen-flavors.gemspec", "lib/chef_gen/flavor.rb", "lib/chef_gen/flavors.rb", "lib/chef_gen/flavors/cucumber.rb", "lib/chef_gen/flavors/cucumber/bundle.rb", "lib/chef_gen/flavors/cucumber/chefdk.rb", "lib/chef_gen/flavors/cucumber/kitchen.rb", "lib/chef_gen/flavors/cucumber/knife.rb", "lib/chef_gen/flavors/cucumber/rake.rb", "lib/chef_gen/flavors/cucumber/regex.rb"]
16
+ s.homepage = "https://github.com/jf647/chef-gen-flavors"
17
17
  s.licenses = ["apache2"]
18
18
  s.rdoc_options = ["--main", "README.md"]
19
19
  s.rubygems_version = "2.4.4"
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
26
26
  s.add_runtime_dependency(%q<little-plugger>, ["~> 1.1"])
27
27
  s.add_runtime_dependency(%q<bogo-ui>, ["~> 0.1"])
28
28
  s.add_development_dependency(%q<rdoc>, ["~> 4.0"])
29
- s.add_development_dependency(%q<chef-dk>, ["~> 0.5"])
29
+ s.add_development_dependency(%q<chef-dk>, ["~> 0.7"])
30
30
  s.add_development_dependency(%q<hoe>, ["~> 3.13"])
31
31
  s.add_development_dependency(%q<hoe-gemspec>, ["~> 1.0"])
32
32
  s.add_development_dependency(%q<rake>, ["~> 10.3"])
@@ -45,7 +45,7 @@ Gem::Specification.new do |s|
45
45
  s.add_dependency(%q<little-plugger>, ["~> 1.1"])
46
46
  s.add_dependency(%q<bogo-ui>, ["~> 0.1"])
47
47
  s.add_dependency(%q<rdoc>, ["~> 4.0"])
48
- s.add_dependency(%q<chef-dk>, ["~> 0.5"])
48
+ s.add_dependency(%q<chef-dk>, ["~> 0.7"])
49
49
  s.add_dependency(%q<hoe>, ["~> 3.13"])
50
50
  s.add_dependency(%q<hoe-gemspec>, ["~> 1.0"])
51
51
  s.add_dependency(%q<rake>, ["~> 10.3"])
@@ -65,7 +65,7 @@ Gem::Specification.new do |s|
65
65
  s.add_dependency(%q<little-plugger>, ["~> 1.1"])
66
66
  s.add_dependency(%q<bogo-ui>, ["~> 0.1"])
67
67
  s.add_dependency(%q<rdoc>, ["~> 4.0"])
68
- s.add_dependency(%q<chef-dk>, ["~> 0.5"])
68
+ s.add_dependency(%q<chef-dk>, ["~> 0.7"])
69
69
  s.add_dependency(%q<hoe>, ["~> 3.13"])
70
70
  s.add_dependency(%q<hoe-gemspec>, ["~> 1.0"])
71
71
  s.add_dependency(%q<rake>, ["~> 10.3"])
@@ -8,7 +8,7 @@ module ChefGen
8
8
  # a plugin framework for creating ChefDK generator flavors
9
9
  class Flavors
10
10
  # the version of the gem
11
- VERSION = '0.8.6'
11
+ VERSION = '0.9.0'
12
12
 
13
13
  extend LittlePlugger path: 'chef_gen/flavor',
14
14
  module: ChefGen::Flavor
@@ -25,27 +25,33 @@ module ChefGen
25
25
  only_plugin ||
26
26
  prompt_for_plugin ||
27
27
  fail('no ChefGen flavors found!')
28
- path = generator_path(selected)
29
- $stdout.puts "using ChefGen flavor '#{selected}' in #{path}"
30
- # take a copy so we can augment it
31
- copy = copy_generator_dir(path)
32
- # augment the copy if the plugin has hooks
33
- run_content_hooks(selected, copy)
34
- # return the path to the copy
35
- copy
28
+ $stdout.puts "using ChefGen flavor '#{selected}'"
29
+
30
+ # return early if we're using the builtin flavor
31
+ return nil if :builtin == selected
32
+
33
+ # get a temp dir
34
+ tmpdir = create_tmpdir(selected)
35
+
36
+ # call the content hooks in the flavor
37
+ @plugins[selected].new(temp_path: tmpdir).add_content
38
+
39
+ # return the temporary directory
40
+ tmpdir
36
41
  end
37
42
 
38
43
  private
39
44
 
40
- # call content hooks in the flavor if it has any
41
- # @param selected [Symbol] the selected flavor
42
- # @param path [String] the temporary generator cookbook path
43
- # @return [void]
44
- def run_content_hooks(selected, path)
45
- flavor_klass = @plugins[selected]
46
- return unless flavor_klass.is_a?(Class)
47
- return unless flavor_klass.instance_methods.include?(:add_content)
48
- @plugins[selected].new(nil).add_content(path)
45
+ # creates a temporary directory for the flavor to populate
46
+ # @param [Symbol] flavor the selected flavor
47
+ # @return [String] the temporary path
48
+ # @api private
49
+ def create_tmpdir(flavor)
50
+ tmpdir = File.join(Dir.mktmpdir('chefgen_flavor.'), flavor.to_s)
51
+ at_exit do
52
+ FileUtils.rm_rf(tmpdir)
53
+ end unless ENV.key?('CHEFGEN_NOCLEANTMP')
54
+ tmpdir
49
55
  end
50
56
 
51
57
  # checks if the plugin to use has been specified in the environment
@@ -77,12 +83,11 @@ module ChefGen
77
83
  @plugins.keys.size == 1 ? @plugins.keys.first : nil
78
84
  end
79
85
 
80
- # :nocov:
81
-
82
86
  # prompts the user for a plugin to use if more than one is available
83
87
  # @return [Symbol] the selected plugin
84
88
  # @raise RuntimeError if an invalid plugin is chosen
85
89
  # @api private
90
+ # :nocov:
86
91
  def prompt_for_plugin
87
92
  return nil unless @plugins.keys.size >= 1
88
93
  require 'bogo-ui'
@@ -93,12 +98,14 @@ module ChefGen
93
98
  ui.fatal 'Invalid flavor chosen'
94
99
  fail 'Invalid ChefGen Flavor'
95
100
  end
101
+ # :nocov:
96
102
 
97
103
  # builds a list of plugins and displays them with as
98
104
  # a number selection list
99
- # @param ui [Bogo::Ui] the ui object to use for display
105
+ # @param [Bogo::Ui] ui the ui object to use for display
100
106
  # @return [Hash] a hash of valid options
101
107
  # @api private
108
+ # :nocov:
102
109
  def plugin_selection(ui)
103
110
  output = [ui.color('Flavors on the menu', :bold)]
104
111
  idx = 1
@@ -115,92 +122,19 @@ module ChefGen
115
122
  ui.info "#{output.join("\n")}\n"
116
123
  valid
117
124
  end
125
+ # :nocov:
118
126
 
119
127
  # builds the description of a flavor for the menu
120
- # @param klass [Class] the class of the flavor
128
+ # @param [Class] klass the class of the flavor
121
129
  # @return [String] the flavor description with version if available
130
+ # @api private
131
+ # :nocov:
122
132
  def plugin_descr(klass)
123
- descr = klass.respond_to?(:description) ? klass.description : ''
124
- if klass.const_defined?(:VERSION)
125
- descr += " v#{klass.const_get(:VERSION, false)}"
126
- end
133
+ descr = klass.const_defined?(:DESC) ? klass.const_get(:DESC) : ''
134
+ descr += " v#{klass.const_get(:VERSION, false)}" if klass.const_defined?(:VERSION)
127
135
  descr
128
136
  end
129
-
130
137
  # :nocov:
131
-
132
- # returns the path to the code_generator cookbook for the
133
- # selected plugin. Handles the built-in template path,
134
- # a plugin that overrides the path and a plugin that uses
135
- # the default path
136
- # @param plugin [Symbol] the selected plugin
137
- # @return [String] the path to the code_generator cookbook
138
- # @api private
139
- def generator_path(plugin)
140
- return builtin_code_generator_path if :builtin == plugin
141
- klass = @plugins[plugin]
142
- classfile = path_to_plugin(klass)
143
- if klass.respond_to?(:code_generator_path)
144
- klass.code_generator_path(classfile)
145
- else
146
- default_code_generator_path(classfile)
147
- end
148
- end
149
-
150
- # returns the path of the file where the description method
151
- # is defined for a given class
152
- # @param klass [Class] the class to look up the method in
153
- # @return [String] the path to the source file for the class
154
- # @api private
155
- def path_to_plugin(klass)
156
- klass.method(:description).source_location[0]
157
- end
158
-
159
- # returns the default path to the code generator cookbook for
160
- # a plugin, which is a directory named 'code_generator' four
161
- # levels above the file which defines the plugin class
162
- # @param classfile [String] the path to the class source, as
163
- # returned from ::path_to_plugin
164
- # @return [String] the path to the code_generator cookbook
165
- # @api private
166
- def default_code_generator_path(classfile)
167
- File.expand_path(
168
- File.join(
169
- classfile,
170
- '..', '..', '..', '..',
171
- 'code_generator'
172
- )
173
- )
174
- end
175
-
176
- # return the path to the code_generator cookbook that comes
177
- # with ChefDK
178
- # @return [String] the path to the code_generator cookbook
179
- # @api private
180
- def builtin_code_generator_path
181
- require 'rubygems'
182
- spec = Gem::Specification.find_by_name('chef-dk')
183
- File.join(
184
- spec.gem_dir, 'lib', 'chef-dk', 'skeletons', 'code_generator'
185
- )
186
- end
187
-
188
- # recursively copies the generator cookbook to a temporary
189
- # directory. Sets up an at_exit handler to remove the
190
- # temporary directory unless CHEFGEN_NOCLEANTMP is set
191
- # in the environment.
192
- # @param srcdir [String] the path to the generator cookbook
193
- # @return [String] the temporary path to generate from
194
- def copy_generator_dir(srcdir)
195
- dstdir = Dir.mktmpdir('chefgen_flavor.')
196
- at_exit do
197
- FileUtils.rm_rf(dstdir)
198
- end unless ENV.key?('CHEFGEN_NOCLEANTMP')
199
- $stdout.puts srcdir
200
- $stdout.puts dstdir
201
- FileUtils.cp_r(srcdir, dstdir)
202
- File.join(dstdir, File.basename(srcdir))
203
- end
204
138
  end
205
139
  end
206
140
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-gen-flavors
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.6
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James FitzGibbon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-06 00:00:00.000000000 Z
11
+ date: 2015-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: little-plugger
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0.5'
61
+ version: '0.7'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0.5'
68
+ version: '0.7'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: hoe
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -270,12 +270,18 @@ description: |-
270
270
  gems, which you can host privately for use within your organization or
271
271
  publicly for the Chef community to use.
272
272
 
273
- At present this is focused primarily on providing templates for generation of
274
- cookbooks, as this is where most organization-specific customization takes place.
275
- Support for the other artifacts that ChefDK can generate may work, but is not
276
- the focus of early releases.
273
+ [chef-gen-flavor-base](https://github.com/jf647/chef-gen-flavor-base) is
274
+ a base class that makes it easy to compose a flavor from reusable
275
+ snippets of functionality, and using it is highly recommended. Using
276
+ chef-gen-flavors on its own is only suitable if you already have a
277
+ template which is a copy of the skeleton provided by ChefDK.
278
+
279
+ At present this is focused primarily on providing templates for
280
+ generation of cookbooks, as this is where most organization-specific
281
+ customization takes place. Support for the other artifacts that ChefDK
282
+ can generate may work, but is not the focus of early releases.
277
283
  email:
278
- - james.i.fitzgibbon@nordstrom.com
284
+ - james@nadt.net
279
285
  executables: []
280
286
  extensions: []
281
287
  extra_rdoc_files:
@@ -291,7 +297,6 @@ files:
291
297
  - README.md
292
298
  - chef-gen-flavors.gemspec
293
299
  - lib/chef_gen/flavor.rb
294
- - lib/chef_gen/flavor_base.rb
295
300
  - lib/chef_gen/flavors.rb
296
301
  - lib/chef_gen/flavors/cucumber.rb
297
302
  - lib/chef_gen/flavors/cucumber/bundle.rb
@@ -300,43 +305,7 @@ files:
300
305
  - lib/chef_gen/flavors/cucumber/knife.rb
301
306
  - lib/chef_gen/flavors/cucumber/rake.rb
302
307
  - lib/chef_gen/flavors/cucumber/regex.rb
303
- - lib/chef_gen/snippet/attributes.rb
304
- - lib/chef_gen/snippet/chef_spec.rb
305
- - lib/chef_gen/snippet/cookbook_base.rb
306
- - lib/chef_gen/snippet/example_file.rb
307
- - lib/chef_gen/snippet/example_template.rb
308
- - lib/chef_gen/snippet/git_init.rb
309
- - lib/chef_gen/snippet/recipes.rb
310
- - lib/chef_gen/snippet/resource_provider.rb
311
- - lib/chef_gen/snippet/standard_ignore.rb
312
- - lib/chef_gen/snippet/style_foodcritic.rb
313
- - lib/chef_gen/snippet/style_rubocop.rb
314
- - lib/chef_gen/snippet/style_tailor.rb
315
- - lib/chef_gen/snippet/test_kitchen.rb
316
- - lib/chef_gen/snippets.rb
317
- - shared/snippet/attributes/attributes_default_rb.erb
318
- - shared/snippet/chef_spec/_rspec.erb
319
- - shared/snippet/chef_spec/spec_chef_runner_context_rb.erb
320
- - shared/snippet/chef_spec/spec_recipes_default_spec_rb.erb
321
- - shared/snippet/chef_spec/spec_spec_helper_rb.erb
322
- - shared/snippet/cookbookbase/Berksfile.erb
323
- - shared/snippet/cookbookbase/CHANGELOG_md.erb
324
- - shared/snippet/cookbookbase/Gemfile.erb
325
- - shared/snippet/cookbookbase/Guardfile.erb
326
- - shared/snippet/cookbookbase/README_md.erb
327
- - shared/snippet/cookbookbase/Rakefile.erb
328
- - shared/snippet/cookbookbase/metadata_rb.erb
329
- - shared/snippet/examplefile/files_default_example_conf
330
- - shared/snippet/exampletemplate/templates_default_example_conf_erb
331
- - shared/snippet/recipes/recipes_default_rb.erb
332
- - shared/snippet/resourceprovider/providers_default_rb.erb
333
- - shared/snippet/resourceprovider/resources_default_rb.erb
334
- - shared/snippet/stylerubocop/_rubocop_yml.erb
335
- - shared/snippet/testkitchen/_kitchen_yml.erb
336
- - shared/snippet/testkitchen/libraries_kitchen_helper_rb
337
- - shared/snippet/testkitchen/test_integration_default_serverspec_recipes_default_spec_rb.erb
338
- - shared/snippet/testkitchen/test_integration_default_serverspec_spec_helper_rb.erb
339
- homepage: https://github.com/Nordstrom/chef-gen-flavors
308
+ homepage: https://github.com/jf647/chef-gen-flavors
340
309
  licenses:
341
310
  - apache2
342
311
  metadata: {}
@@ -1,266 +0,0 @@
1
- require 'chef-dk/generator'
2
-
3
- module ChefGen
4
- # a base for ChefDK Template Flavors
5
- class FlavorBase
6
- # the target path of 'chef generate'
7
- # @return [String] path
8
- attr_reader :target_path
9
-
10
- # directories to create
11
- # @return [Array] list of directories
12
- attr_reader :directories
13
-
14
- # files to create unconditionally
15
- # @return [Array] list of destination filenames
16
- attr_reader :files
17
-
18
- # files to create only if they do not exist
19
- # @return [Array] list of destination filenames
20
- attr_reader :files_if_missing
21
-
22
- # templates to render unconditionally
23
- # @return [Array] list of destination filenames
24
- attr_reader :templates
25
-
26
- # templates to render only if they do not exist
27
- # @return [Array] list of destination filenames
28
- attr_reader :templates_if_missing
29
-
30
- # an informational block about how the user should proceed
31
- # @return [String] instructions
32
- attr_accessor :next_steps
33
-
34
- # whether to fail if files would be overwritten
35
- # @return [Boolean] true to fail on attempted overwrite
36
- attr_accessor :fail_on_clobber
37
-
38
- # whether to report the actions that were taken
39
- # @return [Boolean] true to report actions
40
- attr_accessor :report_actions
41
-
42
- # creates a new flavor object
43
- # @param recipe [Chef::Recipe] the recipe into which
44
- # resources will be injected
45
- # @return [self]
46
- def initialize(recipe)
47
- # store the recipe we'll be injecting resources into
48
- @recipe = recipe
49
-
50
- # derive our target path
51
- ctx = generator_context
52
- @target_path = File.expand_path(
53
- File.join(ctx.cookbook_root, ctx.cookbook_name)
54
- )
55
-
56
- # set defaults
57
- @report_actions = true
58
- @fail_on_clobber = !ctx.respond_to?(:clobber)
59
- @directories = []
60
- %w(directories files files_if_missing templates
61
- templates_if_missing actions_taken failures).each do |varname|
62
- instance_variable_set("@#{varname}".to_sym, [])
63
- end
64
-
65
- # call initializers defined by snippets
66
- methods_by_pattern(/^init_/).each do |m|
67
- send(m)
68
- end
69
- end
70
-
71
- # find all public methods of the flavor starting with content_
72
- # and calls them, passing the path as the sole parameter
73
- # @param path [String] the path to the copy of the generator cookbook
74
- # @return [void]
75
- def add_content(path)
76
- methods_by_pattern(/^content_/).each do |m|
77
- send(m, path)
78
- end
79
- end
80
-
81
- # copy a snippet content file to the temporary generator path,
82
- # creating the destination directory if it does not already exist
83
- # @param src [String] the source file
84
- # @param dst [String] the destination file
85
- # @return [void]
86
- def copy_snippet_file(src, dst)
87
- # make sure the parent of the destination exists
88
- parent = File.dirname(dst)
89
- FileUtils.mkpath(parent) unless Dir.exist?(parent)
90
- # copy the file
91
- FileUtils.copy_file(src, dst)
92
- end
93
-
94
- # a proxy to ChefDK's generator context
95
- # @return [ChefDK::Generator::Context]
96
- def generator_context
97
- ChefDK::Generator.context
98
- end
99
-
100
- # generates the Chef resources that the plugin has declared
101
- # @return [void]
102
- def generate
103
- add_target_path
104
- run_snippets
105
- after_run_snippets if respond_to?(:after_run_snippets)
106
- add_directories
107
- add_files
108
- add_templates
109
- unless @failures.empty?
110
- @failures.each { |f| $stderr.puts f }
111
- fail 'errors during generation'
112
- end
113
- report_actions_taken(@actions_taken) \
114
- if @report_actions && @actions_taken
115
- display_next_steps(@next_steps) if @next_steps
116
- end
117
-
118
- # given a destination file, returns a flattened source
119
- # filename by replacing / and . with _
120
- # @param path [String] the destination file
121
- # @return [String] the flattened source file
122
- # @example convert a destination file
123
- # source_path('spec/spec_helper.rb') #=> 'spec_spec_helper_rb'
124
- def source_path(path)
125
- path.tr('/.', '_')
126
- end
127
-
128
- private
129
-
130
- # creates a directory resource for the target
131
- # @return [void]
132
- def add_target_path
133
- @recipe.send(:directory, @target_path)
134
- @actions_taken << "create directory #{@target_path}"
135
- end
136
-
137
- # find all public methods of the flavor starting with snippet_
138
- # and calls them
139
- # @return [void]
140
- # @yield [Chef::Recipe] the recipe into which the mixin can inject
141
- # resources
142
- # @api private
143
- def run_snippets
144
- methods_by_pattern(/^snippet_/).each do |m|
145
- send(m, @recipe)
146
- end
147
- end
148
-
149
- # returns a list of public methods that match a pattern
150
- # @param pattern [Regexp] the pattern to match methods against
151
- # @return [Array] a list of sorted methods
152
- def methods_by_pattern(pattern)
153
- public_methods.select do |m|
154
- m.to_s =~ pattern
155
- end
156
- end
157
-
158
- # declares a directory resource for each element of @directories
159
- # @return [void]
160
- # @api private
161
- def add_directories
162
- @directories.flatten.each do |dirname|
163
- path = File.join(@target_path, dirname)
164
- @recipe.send(:directory, path)
165
- @actions_taken << "create directory #{path}"
166
- end
167
- end
168
-
169
- # declares a cookbook_file resource for each element of '#files' and
170
- # '#files_if_missing', respecting the value of '#fail_on_clobber'
171
- # @return [void]
172
- # @api private
173
- def add_files
174
- add_render(
175
- @files,
176
- suffix: '', resource: :cookbook_file, resource_action: :create
177
- )
178
- add_render(
179
- @files_if_missing,
180
- suffix: '', clobberfail: false, resource: :cookbook_file
181
- )
182
- end
183
-
184
- # declares a template resource for each element of '#templates' and
185
- # '#templates_if_missing', respecting the value of '#fail_on_clobber'
186
- # @return [void]
187
- # @api private
188
- def add_templates
189
- add_render(@templates, resource_action: :create)
190
- add_render(@templates_if_missing, clobberfail: false)
191
- end
192
-
193
- # does the heavy lifting for add_files and add_templates
194
- # @param things [Array] the list of things to declare
195
- # @param suffix [String] a suffix to add to the source file
196
- # @param clobberfail [Boolean] whether to protect against
197
- # overwriting files
198
- # @param resource [Symbol] the symbolized Chef resource to declare
199
- # @param resource_action [Symbol] the action to give the resource
200
- # @param attrs [Hash] additional attributes to send to the resource.
201
- # Keys are methods, values are parameters
202
- # @return [void]
203
- # @api private
204
- def add_render( # rubocop:disable Metrics/ParameterLists
205
- things,
206
- suffix: '.erb', clobberfail: @fail_on_clobber,
207
- resource: :template, resource_action: :create_if_missing,
208
- attrs: {}
209
- )
210
- things.flatten.each do |filename|
211
- src = "#{source_path(filename)}#{suffix}"
212
- dst = File.join(@target_path, filename)
213
- if clobberfail && File.exist?(dst)
214
- @failures << "tried to overwrite file #{dst}"
215
- else
216
- _add_resource(resource, src, dst, resource_action, attrs)
217
- end
218
- end
219
- end
220
-
221
- # adds a resource to the recipe
222
- # @api private
223
- def _add_resource(type, src, dst, action, attrs)
224
- @recipe.send(type, dst) do
225
- # :nocov:
226
- source src
227
- action action
228
- helpers(ChefDK::Generator::TemplateHelper) \
229
- if :template == type
230
- attrs.each do |attr, value|
231
- send attr, value
232
- end
233
- # :nocov:
234
- end
235
- @actions_taken << "add resource #{type}[#{dst}]"
236
- end
237
-
238
- # reports on the actions taken by the plugin
239
- # @param actions [Array] the list of actions taken
240
- # @return [void]
241
- # @api private
242
- def report_actions_taken(actions)
243
- @recipe.send(:ruby_block, 'report_actions_taken') do
244
- # :nocov:
245
- block do
246
- $stdout.puts "\n\nactions taken:"
247
- actions.each { |a| $stdout.puts " #{a}" }
248
- end
249
- # :nocov:
250
- end
251
- end
252
-
253
- # displays the next steps for the user to take
254
- # @return [void]
255
- # @api private
256
- def display_next_steps(next_steps)
257
- @recipe.send(:ruby_block, 'display_next_steps') do
258
- # :nocov:
259
- block do
260
- $stdout.puts next_steps
261
- end
262
- # :nocov:
263
- end
264
- end
265
- end
266
- end