chef-gen-flavor-base 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/History.md +6 -0
  3. data/LICENSE +17 -0
  4. data/Manifest.txt +50 -0
  5. data/README.md +818 -0
  6. data/chef-gen-flavor-base.gemspec +84 -0
  7. data/lib/chef_gen/flavor_base.rb +185 -0
  8. data/lib/chef_gen/flavor_base/copy_helpers.rb +45 -0
  9. data/lib/chef_gen/flavor_base/resource_helpers.rb +110 -0
  10. data/lib/chef_gen/snippet/actions_taken.rb +82 -0
  11. data/lib/chef_gen/snippet/attributes.rb +35 -0
  12. data/lib/chef_gen/snippet/chef_spec.rb +121 -0
  13. data/lib/chef_gen/snippet/cookbook_base.rb +135 -0
  14. data/lib/chef_gen/snippet/debugging.rb +26 -0
  15. data/lib/chef_gen/snippet/example_file.rb +36 -0
  16. data/lib/chef_gen/snippet/example_template.rb +36 -0
  17. data/lib/chef_gen/snippet/git_init.rb +36 -0
  18. data/lib/chef_gen/snippet/guard.rb +70 -0
  19. data/lib/chef_gen/snippet/next_steps.rb +44 -0
  20. data/lib/chef_gen/snippet/no_clobber.rb +62 -0
  21. data/lib/chef_gen/snippet/recipes.rb +35 -0
  22. data/lib/chef_gen/snippet/resource_provider.rb +37 -0
  23. data/lib/chef_gen/snippet/standard_ignore.rb +85 -0
  24. data/lib/chef_gen/snippet/style_foodcritic.rb +73 -0
  25. data/lib/chef_gen/snippet/style_rubocop.rb +115 -0
  26. data/lib/chef_gen/snippet/style_tailor.rb +64 -0
  27. data/lib/chef_gen/snippet/test_kitchen.rb +129 -0
  28. data/lib/chef_gen/snippet_base.rb +46 -0
  29. data/lib/chef_gen/snippets.rb +24 -0
  30. data/shared/snippet/attributes/templates/default/attributes_default_rb.erb +8 -0
  31. data/shared/snippet/chef_spec/templates/default/_rspec.erb +2 -0
  32. data/shared/snippet/chef_spec/templates/default/spec_chef_runner_context_rb.erb +36 -0
  33. data/shared/snippet/chef_spec/templates/default/spec_recipes_default_spec_rb.erb +7 -0
  34. data/shared/snippet/chef_spec/templates/default/spec_spec_helper_rb.erb +95 -0
  35. data/shared/snippet/cookbook_base/templates/default/Berksfile.erb +12 -0
  36. data/shared/snippet/cookbook_base/templates/default/CHANGELOG_md.erb +5 -0
  37. data/shared/snippet/cookbook_base/templates/default/Gemfile.erb +18 -0
  38. data/shared/snippet/cookbook_base/templates/default/README_md.erb +92 -0
  39. data/shared/snippet/cookbook_base/templates/default/Rakefile.erb +20 -0
  40. data/shared/snippet/cookbook_base/templates/default/metadata_rb.erb +13 -0
  41. data/shared/snippet/example_file/files/default/files_default_example_conf +34 -0
  42. data/shared/snippet/example_template/files/default/templates_default_example_conf_erb +22 -0
  43. data/shared/snippet/guard/templates/default/Guardfile.erb +16 -0
  44. data/shared/snippet/recipes/templates/default/recipes_default_rb.erb +9 -0
  45. data/shared/snippet/resource_provider/templates/default/providers_default_rb.erb +20 -0
  46. data/shared/snippet/resource_provider/templates/default/resources_default_rb.erb +9 -0
  47. data/shared/snippet/style_rubocop/templates/default/_rubocop_yml.erb +31 -0
  48. data/shared/snippet/test_kitchen/libraries/kitchen_helper.rb +13 -0
  49. data/shared/snippet/test_kitchen/templates/default/_kitchen_yml.erb +30 -0
  50. data/shared/snippet/test_kitchen/templates/default/test_integration_default_serverspec_recipes_default_spec_rb.erb +16 -0
  51. data/shared/snippet/test_kitchen/templates/default/test_integration_default_serverspec_spec_helper_rb.erb +7 -0
  52. metadata +372 -0
@@ -0,0 +1,84 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # stub: chef-gen-flavor-base 0.9.0.20150909153100 ruby lib
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "chef-gen-flavor-base"
6
+ s.version = "0.9.0.20150909153100"
7
+
8
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
+ s.require_paths = ["lib"]
10
+ s.authors = ["James FitzGibbon"]
11
+ s.date = "2015-09-09"
12
+ s.description = "chef-gen-flavor-base is a base class to make it easy to create 'flavors'\nfor use with\n[chef-gen-flavors](https://github.com/jf647/chef-gen-flavors).\n\nchef-gen-flavors plugs into the 'chef generate' command provided by\nChefDK to let you provide an alternate template for cookbooks and other\nchef components.\n\nThis gem simply provides a class your flavor can derive from; templates\nare provided by separate gems, which you can host privately for use\nwithin your organization or publicly for the Chef community to use.\n\nAn example flavor that demonstrates how to use this gem is distributed\nseparately:\n[chef-gen-flavor-example](https://github.com/jf647/chef-gen-flavor-example)\n\nAt present this is focused primarily on providing templates for\ngeneration of cookbooks, as this is where most organization-specific\ncustomization takes place. Support for the other artifacts that ChefDK\ncan generate may work, but is not the focus of early releases."
13
+ s.email = ["james@nadt.net"]
14
+ s.extra_rdoc_files = ["History.md", "Manifest.txt", "README.md"]
15
+ s.files = ["History.md", "LICENSE", "Manifest.txt", "README.md", "chef-gen-flavor-base.gemspec", "lib/chef_gen/flavor_base.rb", "lib/chef_gen/flavor_base/copy_helpers.rb", "lib/chef_gen/flavor_base/resource_helpers.rb", "lib/chef_gen/snippet/actions_taken.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/debugging.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/guard.rb", "lib/chef_gen/snippet/next_steps.rb", "lib/chef_gen/snippet/no_clobber.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/snippet_base.rb", "lib/chef_gen/snippets.rb", "shared/snippet/attributes/templates/default/attributes_default_rb.erb", "shared/snippet/chef_spec/templates/default/_rspec.erb", "shared/snippet/chef_spec/templates/default/spec_chef_runner_context_rb.erb", "shared/snippet/chef_spec/templates/default/spec_recipes_default_spec_rb.erb", "shared/snippet/chef_spec/templates/default/spec_spec_helper_rb.erb", "shared/snippet/cookbook_base/templates/default/Berksfile.erb", "shared/snippet/cookbook_base/templates/default/CHANGELOG_md.erb", "shared/snippet/cookbook_base/templates/default/Gemfile.erb", "shared/snippet/cookbook_base/templates/default/README_md.erb", "shared/snippet/cookbook_base/templates/default/Rakefile.erb", "shared/snippet/cookbook_base/templates/default/metadata_rb.erb", "shared/snippet/example_file/files/default/files_default_example_conf", "shared/snippet/example_template/files/default/templates_default_example_conf_erb", "shared/snippet/guard/templates/default/Guardfile.erb", "shared/snippet/recipes/templates/default/recipes_default_rb.erb", "shared/snippet/resource_provider/templates/default/providers_default_rb.erb", "shared/snippet/resource_provider/templates/default/resources_default_rb.erb", "shared/snippet/style_rubocop/templates/default/_rubocop_yml.erb", "shared/snippet/test_kitchen/libraries/kitchen_helper.rb", "shared/snippet/test_kitchen/templates/default/_kitchen_yml.erb", "shared/snippet/test_kitchen/templates/default/test_integration_default_serverspec_recipes_default_spec_rb.erb", "shared/snippet/test_kitchen/templates/default/test_integration_default_serverspec_spec_helper_rb.erb"]
16
+ s.homepage = "https://github.com/jf647/chef-gen-flavor-base"
17
+ s.licenses = ["apache2"]
18
+ s.rdoc_options = ["--main", "README.md"]
19
+ s.rubygems_version = "2.4.4"
20
+ s.summary = "chef-gen-flavor-base is a base class to make it easy to create 'flavors' for use with [chef-gen-flavors](https://github.com/jf647/chef-gen-flavors)"
21
+
22
+ if s.respond_to? :specification_version then
23
+ s.specification_version = 4
24
+
25
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
+ s.add_runtime_dependency(%q<chef-gen-flavors>, ["~> 0.9"])
27
+ s.add_runtime_dependency(%q<hooks>, ["~> 0.4"])
28
+ s.add_development_dependency(%q<rdoc>, ["~> 4.0"])
29
+ s.add_development_dependency(%q<chef-dk>, ["~> 0.7"])
30
+ s.add_development_dependency(%q<hoe>, ["~> 3.13"])
31
+ s.add_development_dependency(%q<hoe-gemspec>, ["~> 1.0"])
32
+ s.add_development_dependency(%q<rake>, ["~> 10.3"])
33
+ s.add_development_dependency(%q<rspec>, ["~> 3.1"])
34
+ s.add_development_dependency(%q<guard>, ["~> 2.12"])
35
+ s.add_development_dependency(%q<guard-rspec>, ["~> 4.2"])
36
+ s.add_development_dependency(%q<guard-rake>, ["~> 0.0"])
37
+ s.add_development_dependency(%q<guard-rubocop>, ["~> 1.2"])
38
+ s.add_development_dependency(%q<simplecov>, ["~> 0.9"])
39
+ s.add_development_dependency(%q<simplecov-console>, ["~> 0.2"])
40
+ s.add_development_dependency(%q<yard>, ["~> 0.8"])
41
+ s.add_development_dependency(%q<aruba>, ["~> 0.6.2"])
42
+ s.add_development_dependency(%q<rspec_junit_formatter>, ["~> 0.2"])
43
+ s.add_development_dependency(%q<fakefs>, ["~> 0.6"])
44
+ else
45
+ s.add_dependency(%q<chef-gen-flavors>, ["~> 0.9"])
46
+ s.add_dependency(%q<hooks>, ["~> 0.4"])
47
+ s.add_dependency(%q<rdoc>, ["~> 4.0"])
48
+ s.add_dependency(%q<chef-dk>, ["~> 0.7"])
49
+ s.add_dependency(%q<hoe>, ["~> 3.13"])
50
+ s.add_dependency(%q<hoe-gemspec>, ["~> 1.0"])
51
+ s.add_dependency(%q<rake>, ["~> 10.3"])
52
+ s.add_dependency(%q<rspec>, ["~> 3.1"])
53
+ s.add_dependency(%q<guard>, ["~> 2.12"])
54
+ s.add_dependency(%q<guard-rspec>, ["~> 4.2"])
55
+ s.add_dependency(%q<guard-rake>, ["~> 0.0"])
56
+ s.add_dependency(%q<guard-rubocop>, ["~> 1.2"])
57
+ s.add_dependency(%q<simplecov>, ["~> 0.9"])
58
+ s.add_dependency(%q<simplecov-console>, ["~> 0.2"])
59
+ s.add_dependency(%q<yard>, ["~> 0.8"])
60
+ s.add_dependency(%q<aruba>, ["~> 0.6.2"])
61
+ s.add_dependency(%q<rspec_junit_formatter>, ["~> 0.2"])
62
+ s.add_dependency(%q<fakefs>, ["~> 0.6"])
63
+ end
64
+ else
65
+ s.add_dependency(%q<chef-gen-flavors>, ["~> 0.9"])
66
+ s.add_dependency(%q<hooks>, ["~> 0.4"])
67
+ s.add_dependency(%q<rdoc>, ["~> 4.0"])
68
+ s.add_dependency(%q<chef-dk>, ["~> 0.7"])
69
+ s.add_dependency(%q<hoe>, ["~> 3.13"])
70
+ s.add_dependency(%q<hoe-gemspec>, ["~> 1.0"])
71
+ s.add_dependency(%q<rake>, ["~> 10.3"])
72
+ s.add_dependency(%q<rspec>, ["~> 3.1"])
73
+ s.add_dependency(%q<guard>, ["~> 2.12"])
74
+ s.add_dependency(%q<guard-rspec>, ["~> 4.2"])
75
+ s.add_dependency(%q<guard-rake>, ["~> 0.0"])
76
+ s.add_dependency(%q<guard-rubocop>, ["~> 1.2"])
77
+ s.add_dependency(%q<simplecov>, ["~> 0.9"])
78
+ s.add_dependency(%q<simplecov-console>, ["~> 0.2"])
79
+ s.add_dependency(%q<yard>, ["~> 0.8"])
80
+ s.add_dependency(%q<aruba>, ["~> 0.6.2"])
81
+ s.add_dependency(%q<rspec_junit_formatter>, ["~> 0.2"])
82
+ s.add_dependency(%q<fakefs>, ["~> 0.6"])
83
+ end
84
+ end
@@ -0,0 +1,185 @@
1
+ require 'chef-dk/generator'
2
+ require 'hooks'
3
+
4
+ require 'chef_gen/flavor_base/copy_helpers'
5
+ require 'chef_gen/flavor_base/resource_helpers'
6
+
7
+ module ChefGen
8
+ # a base for ChefDK Template Flavors
9
+ class FlavorBase
10
+ include Hooks
11
+ include ChefGen::FlavorBase::CopyHelpers
12
+ include ChefGen::FlavorBase::ResourceHelpers
13
+
14
+ # the version of the gem
15
+ VERSION = '0.9.0'
16
+
17
+ # define common hooks
18
+ define_hooks :before_initialize, :after_initialize,
19
+ :before_snippet_construct, :after_snippet_construct
20
+
21
+ # define setup hooks
22
+ define_hooks :before_add_content, :after_add_content,
23
+ :do_add_content,
24
+ :before_copy_content, :after_copy_content
25
+
26
+ # define generate hooks
27
+ define_hooks :before_declare_resources, :after_declare_resources,
28
+ :do_declare_resources,
29
+ :before_add_resources, :after_add_resources,
30
+ :before_add_directories, :after_add_directories,
31
+ :before_add_files, :after_add_files,
32
+ :before_add_templates, :after_add_templates
33
+
34
+ # the type of object being generated (cookbook, repo, etc.)
35
+ # @return [String] the type of object being generated
36
+ attr_reader :type
37
+
38
+ # a list of snippet classes to mix in
39
+ # @return [Array<Class>] list of snippet classes
40
+ attr_reader :snippets
41
+
42
+ # a list of pairs of src/dst files or directories to copy into
43
+ # the temporary directory.
44
+ # @return [Array<Array>] list of [src, dst] pairs
45
+ attr_reader :tocopy
46
+
47
+ # a list of directory resources
48
+ # @return [Array<String>] target path relative to cookbook root
49
+ attr_reader :directories
50
+
51
+ # a list of file resources with action :create
52
+ # @return [Array<String>] target path relative to cookbook root
53
+ attr_reader :files
54
+
55
+ # a list of file resources with action :create_if_missing
56
+ # @return [Array<String>] target path relative to cookbook root
57
+ attr_reader :files_if_missing
58
+
59
+ # a list of template resources with action :create
60
+ # @return [Array<String>] target path relative to cookbook root
61
+ attr_reader :templates
62
+
63
+ # a list of template resources with action :create_if_missing
64
+ # @return [Array<String>] target path relative to cookbook root
65
+ attr_reader :templates_if_missing
66
+
67
+ # @overload initialize(temp_path)
68
+ # initializes the flavor in setup mode
69
+ # @param temp_path [String] the temporary directory provided
70
+ # by chef-gen-flavors
71
+ # @return [self]
72
+ # @overload initialize(type, recipe)
73
+ # initializes the flavor in generate mode
74
+ # @param type [String] the type of object being generated
75
+ # when constructed by ChefDK
76
+ # @param recipe [Chef::Recipe] the recipe into which to inject
77
+ # resources when constructed by ChefDK
78
+ # @return [self]
79
+ def initialize(temp_path: nil, type: nil, recipe: nil)
80
+ # run before hook
81
+ run_hook :before_initialize
82
+
83
+ # set up instance variables
84
+ @recipe = recipe
85
+
86
+ # start with an empty list of snippets
87
+ @snippets = []
88
+ @enabled_snippets = {}
89
+
90
+ if setup_mode?
91
+ @temp_path = temp_path
92
+ # in setup mode, start with an empty list of things to copy
93
+ @tocopy = []
94
+ else
95
+ @type = type
96
+ # in generate mode, start empty dir, file and template lists
97
+ @directories = []
98
+ @files = []
99
+ @files_if_missing = []
100
+ @templates = []
101
+ @templates_if_missing = []
102
+ end
103
+
104
+ # run after hook
105
+ run_hook :after_initialize
106
+ end
107
+
108
+ # determines if the flavor is in setup mode
109
+ # @return [Boolean] true if the flavor is in setup mode, creating
110
+ # the temporary directory
111
+ def setup_mode?
112
+ @recipe.nil?
113
+ end
114
+
115
+ # determines if the flavor is in generate mode
116
+ # @return [Boolean] true if the flavor is in generate mode, used
117
+ # by ChefDK to create an object
118
+ def generate_mode?
119
+ !setup_mode?
120
+ end
121
+
122
+ # constructs and calls the #add_content of each snippet, then calls
123
+ # #copy_content to copy the files to the temporary directory
124
+ # @return [void]
125
+ def add_content
126
+ # construct each snippet in setup mode
127
+ run_hook :before_snippet_construct
128
+ snippets.map! { |s| s.new(flavor: self) }
129
+ mark_enabled_snippets
130
+ run_hook :after_snippet_construct
131
+
132
+ # call hooks to add content
133
+ run_hook :before_add_content
134
+ run_hook :do_add_content
135
+ run_hook :after_add_content
136
+
137
+ # copy queued content
138
+ run_hook :before_copy_content
139
+ copy_content
140
+ run_hook :after_copy_content
141
+ end
142
+
143
+ # constructs and calls the #declare_resources method of each snippet,
144
+ # then calls #add_resources to add the resources to the recipe
145
+ # @return [void]
146
+ def declare_resources
147
+ # declare the target directory
148
+ @recipe.send(:directory, destination_path('.'))
149
+
150
+ # construct each snippet in generate mode
151
+ run_hook :before_snippet_construct
152
+ snippets.map! { |s| s.new(flavor: self, recipe: @recipe) }
153
+ mark_enabled_snippets
154
+ run_hook :after_snippet_construct
155
+
156
+ # call hooks to add content
157
+ run_hook :before_declare_resources
158
+ run_hook :do_declare_resources
159
+ run_hook :after_declare_resources
160
+
161
+ # add queued resources to the recipe
162
+ run_hook :before_add_resources
163
+ add_resources
164
+ run_hook :after_add_resources
165
+ end
166
+
167
+ # a predicate to determine if a snippet has been included in a flavor
168
+ # @param [String] name the NAME constant of the snippet
169
+ # @return [Boolean] true if the snippet has been enabled
170
+ def snippet?(name)
171
+ @enabled_snippets.key?(name)
172
+ end
173
+
174
+ private
175
+
176
+ # populates a hash of enabled snippets for use in snippet?
177
+ # @return [void]
178
+ # @api private
179
+ def mark_enabled_snippets
180
+ @enabled_snippets = snippets.map do |s|
181
+ [s.class.const_get(:NAME), 1]
182
+ end.to_h
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,45 @@
1
+ module ChefGen
2
+ # a base for ChefDK Template Flavors
3
+ class FlavorBase
4
+ # helpers to copy files from flavors and snippets to the temporary
5
+ # directory; used in the setup phase
6
+ module CopyHelpers
7
+ private
8
+
9
+ # copies content enqueued by the flavor and snippets to the
10
+ # temporary directory. Uses the list of things to copy in the
11
+ # #tocopy list. In each pair, src is an absolute file or
12
+ # directory and dst is relative to the generator cookbook path.
13
+ # If copying to the root of the temp dir, pair[1] can be nil.
14
+ # Implemented using FileUtils::cp_r, so refer to that for details
15
+ # of the different patterns you can use.
16
+ # @return [void]
17
+ # @api private
18
+ def copy_content
19
+ @tocopy.each do |pair|
20
+ src = pair[0]
21
+ dst = File.expand_path(File.join(@temp_path, pair[1] || ''))
22
+ dstdir = File.dirname(dst)
23
+ FileUtils.mkpath(dstdir) unless File.exist?(dstdir)
24
+ FileUtils.cp_r(src, dst)
25
+ end
26
+
27
+ # clear out the list of things to copy so that snippets can
28
+ # re-load it and call copy_content again if needed
29
+ @tocopy = []
30
+ end
31
+
32
+ # returns the path to static content distributed with a flavor
33
+ # @param file [String] the file to generate the path from
34
+ # @return [String] the path the static content relative to the file
35
+ # @api private
36
+ def static_content_path(file)
37
+ File.expand_path(
38
+ File.join(
39
+ File.dirname(file), '..', '..', '..', 'shared', 'flavor', self.class::NAME
40
+ )
41
+ )
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,110 @@
1
+ module ChefGen
2
+ # a base for ChefDK Template Flavors
3
+ class FlavorBase
4
+ # helpers to add resources to recipes; used in the generate phase
5
+ module ResourceHelpers
6
+ # adds directories to the recipes
7
+ # @param [Array<String>] directories the directories to create
8
+ # @return [void]
9
+ # @api private
10
+ def add_directories(directories)
11
+ run_hook :before_add_directories, directories
12
+ directories.each do |dir|
13
+ dst = destination_path(dir)
14
+ @recipe.send(:directory, dst)
15
+ end
16
+ run_hook :after_add_directories, directories
17
+ end
18
+
19
+ # adds files to the recipes. Without content, creates a cookbook_file
20
+ # resource, otherwise creates a file resource.
21
+ # @param files [Array<String>] list of files relative to target root.
22
+ # If content is provided, this should only contain one file
23
+ # @param resource_action [Symbol] the action to send to the resource
24
+ # @param type [Symbol] the type of resource, :file or :cookbook_file
25
+ # @param attrs [Hash] additional attributes to pass to the resource
26
+ # @return [void]
27
+ # @api private
28
+ def add_files(files, resource_action = :create_if_missing, type = :cookbook_file, attrs = {})
29
+ run_hook :before_add_files, files, resource_action, type, attrs
30
+ files.each do |file|
31
+ src = source_path(file)
32
+ # :nocov:
33
+ @recipe.send(type, destination_path(file)) do
34
+ action resource_action
35
+ source src if :cookbook_file == type
36
+ attrs.each { |a, v| send a, v }
37
+ end
38
+ # :nocov:
39
+ end
40
+ run_hook :after_add_files, files, resource_action, type, attrs
41
+ end
42
+
43
+ # adds templates to the recipes
44
+ # @param templates [Array<String>] list of templates relative to target root
45
+ # @param resource_action [Symbol] the action to send to the resource
46
+ # @param attrs [Hash] additional attributes to pass to the resource
47
+ # @return [void]
48
+ # @api private
49
+ def add_templates(templates, resource_action = :create_if_missing, attrs = {})
50
+ run_hook :before_add_templates, templates, resource_action, attrs
51
+ templates.each do |template|
52
+ src = "#{source_path(template)}.erb"
53
+ # :nocov:
54
+ @recipe.send(:template, destination_path(template)) do
55
+ source src
56
+ action resource_action
57
+ helpers ChefDK::Generator::TemplateHelper
58
+ attrs.each { |a, v| send a, v }
59
+ end
60
+ # :nocov:
61
+ run_hook :after_add_templates, templates, resource_action, attrs
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ # given a destination file, returns a flattened source
68
+ # filename by replacing / and . with _
69
+ # @param path [String] the destination file
70
+ # @return [String] the flattened source file
71
+ # @example convert a destination file
72
+ # source_path('spec/spec_helper.rb') #=> 'spec_spec_helper_rb'
73
+ def source_path(path)
74
+ path.tr('/.', '_')
75
+ end
76
+
77
+ # returns the destination path for a file in the `chef generate`
78
+ # target directory
79
+ # @param path [String] a path to append to the target dir
80
+ # @return [String] the absolute destination path
81
+ # @api private
82
+ def destination_path(path = '')
83
+ File.expand_path(File.join(generate_target, path))
84
+ end
85
+
86
+ # returns the target directory of `chef generate`
87
+ # @return [String]
88
+ # @api private
89
+ def generate_target
90
+ @generate_target ||= begin
91
+ ctx = ChefDK::Generator.context
92
+ File.expand_path(
93
+ File.join(ctx.cookbook_root, ctx.cookbook_name)
94
+ )
95
+ end
96
+ end
97
+
98
+ # adds declared directories / files / templates resources to the recipe
99
+ # @return [void]
100
+ # @api private
101
+ def add_resources
102
+ add_directories(@directories)
103
+ add_files(@files, :create)
104
+ add_files(@files_if_missing)
105
+ add_templates(@templates, :create)
106
+ add_templates(@templates_if_missing)
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,82 @@
1
+ require 'chef_gen/snippet_base'
2
+
3
+ module ChefGen
4
+ module Snippet
5
+ # provides an accumulator of the actions were taken by the
6
+ # flavor during generation and a ruby_block resource to display
7
+ # them at the end of the generate phase
8
+ class ActionsTaken < ChefGen::SnippetBase
9
+ # the name of the snippet
10
+ NAME = 'actions_taken'
11
+
12
+ private
13
+
14
+ # @!attribute [rw] actions_taken
15
+ # @return [Array<String>] the actions taken by the flavor
16
+
17
+ # initializes the snippet in generate mode
18
+ # @return [void]
19
+ # @api private
20
+ def initialize_generate
21
+ super
22
+ @flavor.class.send(:attr_accessor, :actions_taken)
23
+ @flavor.actions_taken = []
24
+
25
+ hook_add_directories
26
+ hook_add_files
27
+ hook_add_templates
28
+ hook_report_actions
29
+ end
30
+
31
+ # adds a hook after add_directories to report on actions
32
+ # @return [void]
33
+ # @api private
34
+ def hook_add_directories
35
+ @flavor.class.after_add_directories do |directories|
36
+ directories.each do |dir|
37
+ actions_taken << "create directory #{dir}"
38
+ end
39
+ end
40
+ end
41
+
42
+ # adds a hook afer add_files to report on actions
43
+ # @return [void]
44
+ # @api private
45
+ def hook_add_files
46
+ @flavor.class.after_add_files do |files, resource_action, type|
47
+ files.each do |file|
48
+ actions_taken << "#{resource_action} #{type} #{file}"
49
+ end
50
+ end
51
+ end
52
+
53
+ # adds a hook after add_templates to report on actions
54
+ # @return [void]
55
+ # @api private
56
+ def hook_add_templates
57
+ @flavor.class.after_add_templates do |templates, resource_action|
58
+ templates.each do |template|
59
+ actions_taken << "#{resource_action} template #{template}"
60
+ end
61
+ end
62
+ end
63
+
64
+ # adds an after hook to declare resources to report on actions taken
65
+ # @return [void]
66
+ # @api private
67
+ def hook_report_actions
68
+ @flavor.class.after_add_resources do
69
+ actions = actions_taken
70
+ @recipe.send(:ruby_block, 'report_actions_taken') do
71
+ # :nocov:
72
+ block do
73
+ $stdout.puts "\n\nactions taken:"
74
+ actions.each { |a| $stdout.puts " #{a}" }
75
+ end
76
+ # :nocov:
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end