poise 2.0.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 (80) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.kitchen.travis.yml +9 -0
  4. data/.kitchen.yml +18 -0
  5. data/.rubocop.yml +2 -0
  6. data/.travis.yml +25 -0
  7. data/.yardopts +5 -0
  8. data/Berksfile +26 -0
  9. data/Berksfile.lock +10 -0
  10. data/CHANGELOG.md +58 -0
  11. data/Gemfile +32 -0
  12. data/LICENSE +202 -0
  13. data/README.md +198 -0
  14. data/Rakefile +17 -0
  15. data/lib/poise.rb +71 -0
  16. data/lib/poise/error.rb +24 -0
  17. data/lib/poise/helpers.rb +33 -0
  18. data/lib/poise/helpers/chefspec_matchers.rb +92 -0
  19. data/lib/poise/helpers/defined_in.rb +111 -0
  20. data/lib/poise/helpers/fused.rb +127 -0
  21. data/lib/poise/helpers/include_recipe.rb +62 -0
  22. data/lib/poise/helpers/inversion.rb +374 -0
  23. data/lib/poise/helpers/inversion/options_provider.rb +41 -0
  24. data/lib/poise/helpers/inversion/options_resource.rb +101 -0
  25. data/lib/poise/helpers/lazy_default.rb +62 -0
  26. data/lib/poise/helpers/lwrp_polyfill.rb +96 -0
  27. data/lib/poise/helpers/notifying_block.rb +78 -0
  28. data/lib/poise/helpers/option_collector.rb +117 -0
  29. data/lib/poise/helpers/resource_name.rb +99 -0
  30. data/lib/poise/helpers/subcontext_block.rb +58 -0
  31. data/lib/poise/helpers/subresources.rb +29 -0
  32. data/lib/poise/helpers/subresources/child.rb +217 -0
  33. data/lib/poise/helpers/subresources/container.rb +165 -0
  34. data/lib/poise/helpers/subresources/default_containers.rb +73 -0
  35. data/lib/poise/helpers/template_content.rb +165 -0
  36. data/lib/poise/provider.rb +55 -0
  37. data/lib/poise/resource.rb +75 -0
  38. data/lib/poise/subcontext.rb +27 -0
  39. data/lib/poise/subcontext/resource_collection.rb +56 -0
  40. data/lib/poise/subcontext/runner.rb +50 -0
  41. data/lib/poise/utils.rb +60 -0
  42. data/lib/poise/utils/resource_provider_mixin.rb +53 -0
  43. data/lib/poise/version.rb +20 -0
  44. data/poise.gemspec +38 -0
  45. data/test/cookbooks/poise_test/attributes/default.rb +17 -0
  46. data/test/cookbooks/poise_test/libraries/app.rb +43 -0
  47. data/test/cookbooks/poise_test/libraries/app_config.rb +46 -0
  48. data/test/cookbooks/poise_test/libraries/inversion.rb +67 -0
  49. data/test/cookbooks/poise_test/metadata.rb +18 -0
  50. data/test/cookbooks/poise_test/recipes/default.rb +25 -0
  51. data/test/cookbooks/poise_test/recipes/inversion.rb +42 -0
  52. data/test/gemfiles/chef-12.0.gemfile +18 -0
  53. data/test/gemfiles/chef-12.1.gemfile +18 -0
  54. data/test/gemfiles/chef-12.2.gemfile +18 -0
  55. data/test/gemfiles/chef-12.gemfile +18 -0
  56. data/test/gemfiles/master.gemfile +20 -0
  57. data/test/integration/default/serverspec/default_spec.rb +35 -0
  58. data/test/integration/default/serverspec/inversion_spec.rb +43 -0
  59. data/test/spec/helpers/chefspec_matchers_spec.rb +45 -0
  60. data/test/spec/helpers/defined_in_spec.rb +62 -0
  61. data/test/spec/helpers/fused_spec.rb +92 -0
  62. data/test/spec/helpers/include_recipe_spec.rb +34 -0
  63. data/test/spec/helpers/inversion/options_resource_spec.rb +212 -0
  64. data/test/spec/helpers/inversion_spec.rb +273 -0
  65. data/test/spec/helpers/lazy_default_spec.rb +74 -0
  66. data/test/spec/helpers/lwrp_polyfill_spec.rb +128 -0
  67. data/test/spec/helpers/notifying_block_spec.rb +87 -0
  68. data/test/spec/helpers/option_collector_spec.rb +82 -0
  69. data/test/spec/helpers/resource_name_spec.rb +39 -0
  70. data/test/spec/helpers/subcontext_block_spec.rb +94 -0
  71. data/test/spec/helpers/subresources/child_spec.rb +339 -0
  72. data/test/spec/helpers/subresources/container_spec.rb +175 -0
  73. data/test/spec/helpers/template_context_spec.rb +147 -0
  74. data/test/spec/poise_spec.rb +185 -0
  75. data/test/spec/provider_spec.rb +28 -0
  76. data/test/spec/resource_spec.rb +85 -0
  77. data/test/spec/spec_helper.rb +18 -0
  78. data/test/spec/utils/resource_provider_mixin_spec.rb +52 -0
  79. data/test/spec/utils_spec.rb +110 -0
  80. metadata +190 -0
@@ -0,0 +1,50 @@
1
+ #
2
+ # Copyright 2013-2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'chef/runner'
18
+
19
+
20
+ module Poise
21
+ module Subcontext
22
+ # A subclass of the normal Chef Runner that migrates delayed notifications
23
+ # to the enclosing run_context instead of running them at the end of the
24
+ # subcontext convergence.
25
+ #
26
+ # @api private
27
+ # @since 1.0.0
28
+ class Runner < Chef::Runner
29
+ def initialize(resource, *args)
30
+ super(*args)
31
+ @resource = resource
32
+ end
33
+
34
+ def run_delayed_notifications(error=nil)
35
+ # If there is an error, just do the normal thing. The return shouldn't
36
+ # ever fire because the superclass re-raises if there is an error.
37
+ return super if error
38
+ delayed_actions.each do |notification|
39
+ notifications = run_context.delayed_notifications(@resource)
40
+ if run_context.delayed_notifications(@resource).any? { |existing_notification| existing_notification.duplicates?(notification) }
41
+ Chef::Log.info( "#{@resource} not queuing delayed action #{notification.action} on #{notification.resource}"\
42
+ " (delayed), as it's already been queued")
43
+ else
44
+ notifications << notification
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,60 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'poise/error'
18
+
19
+
20
+ module Poise
21
+ module Utils
22
+ autoload :ResourceProviderMixin, 'poise/utils/resource_provider_mixin'
23
+
24
+ extend self
25
+
26
+ # Find the cookbook name for a given filename. The can used to find the
27
+ # cookbook that corresponds to a caller of a file.
28
+ #
29
+ # @param run_context [Chef::RunContext] Context to check.
30
+ # @param filename [String] Absolute filename to check for.
31
+ # @return [String]
32
+ # @example
33
+ # def my_thing
34
+ # caller_filename = caller.first.split(':').first
35
+ # cookbook = Poise::Utils.find_cookbook_name(run_context, caller_filename)
36
+ # # ...
37
+ # end
38
+ def find_cookbook_name(run_context, filename)
39
+ run_context.cookbook_collection.each do |name, ver|
40
+ # This special method is added by Halite::Gem#as_cookbook_version.
41
+ if ver.respond_to?(:halite_root)
42
+ # The join is there because ../poise-ruby/lib starts with ../poise so
43
+ # we want a trailing /.
44
+ if filename.start_with?(File.join(ver.halite_root, ''))
45
+ return name
46
+ end
47
+ else
48
+ Chef::CookbookVersion::COOKBOOK_SEGMENTS.each do |seg|
49
+ ver.segment_filenames(seg).each do |file|
50
+ if file == filename
51
+ return name
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ raise Poise::Error.new("Unable to find cookbook for file #{filename.inspect}")
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,53 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+
18
+ module Poise
19
+ module Utils
20
+ # A mixin to dispatch other mixins with resource and provider
21
+ # implementations. The module this is included in must have Resource and
22
+ # Provider sub-modules.
23
+ #
24
+ # @since 2.0.0
25
+ # @example
26
+ # module MyHelper
27
+ # include Poise::Utils::ResourceProviderMixin
28
+ # module Resource
29
+ # # ...
30
+ # end
31
+ #
32
+ # module Provider
33
+ # # ...
34
+ # end
35
+ # end
36
+ module ResourceProviderMixin
37
+ # @!classmethods
38
+ module ClassMethods
39
+ def included(klass)
40
+ super
41
+ klass.extend(ClassMethods)
42
+ if klass < Chef::Resource
43
+ klass.class_exec { include self::Resource }
44
+ elsif klass < Chef::Provider
45
+ klass.class_exec { include self::Provider }
46
+ end
47
+ end
48
+ end
49
+
50
+ extend ClassMethods
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,20 @@
1
+ #
2
+ # Copyright 2013-2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+
18
+ module Poise
19
+ VERSION = '2.0.0'
20
+ end
@@ -0,0 +1,38 @@
1
+ #
2
+ # Copyright 2013-2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ lib = File.expand_path('../lib', __FILE__)
18
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
19
+ require 'poise/version'
20
+
21
+ Gem::Specification.new do |spec|
22
+ spec.name = 'poise'
23
+ spec.version = Poise::VERSION
24
+ spec.authors = ['Noah Kantrowitz']
25
+ spec.email = %w{noah@coderanger.net}
26
+ spec.description = "Helpers for writing extensible Chef cookbooks."
27
+ spec.summary = spec.description
28
+ spec.homepage = 'https://github.com/poise/poise'
29
+ spec.license = 'Apache 2.0'
30
+
31
+ spec.files = `git ls-files`.split($/)
32
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
33
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
34
+ spec.require_paths = %w{lib}
35
+
36
+ spec.add_dependency 'halite', '~> 1.0'
37
+ spec.add_development_dependency 'poise-boiler', '~> 1.0'
38
+ end
@@ -0,0 +1,17 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ default['poise_test']['c']['provider'] = 'two'
@@ -0,0 +1,43 @@
1
+ #
2
+ # Copyright 2013-2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'poise'
18
+
19
+
20
+ class Chef
21
+ class Resource::App < Resource
22
+ include Poise(container: true)
23
+ default_action(:install)
24
+
25
+ attribute(:path, kind_of: String, name_attribute: true)
26
+ attribute(:user, kind_of: String, default: 'root')
27
+ attribute(:group, kind_of: String, default: 'root')
28
+ end
29
+
30
+ class Provider::App < Provider
31
+ include Poise
32
+
33
+ def action_install
34
+ notifying_block do
35
+ directory new_resource.path do
36
+ owner new_resource.user
37
+ group new_resource.group
38
+ mode '755'
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,46 @@
1
+ #
2
+ # Copyright 2013-2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require_relative 'app'
18
+
19
+ class Chef
20
+ class Resource::AppConfig < Resource
21
+ include Poise(App)
22
+ default_action(:create)
23
+
24
+ attribute('', template: true, required: true)
25
+ attribute(:config_name, kind_of: String, default: lazy { name.split('::').last })
26
+
27
+ def path
28
+ ::File.join(parent.path, config_name+'.conf')
29
+ end
30
+ end
31
+
32
+ class Provider::AppConfig < Provider
33
+ include Poise
34
+
35
+ def action_create
36
+ notifying_block do
37
+ file new_resource.path do
38
+ owner new_resource.parent.user
39
+ group new_resource.parent.group
40
+ mode '644'
41
+ content new_resource.content
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,67 @@
1
+ #
2
+ # Copyright 2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'poise'
18
+
19
+
20
+ module PoiseTest
21
+ module Inversion
22
+ class Resource < Chef::Resource
23
+ include Poise(inversion: true)
24
+ provides(:poise_test_inversion)
25
+ actions(:run)
26
+
27
+ attribute(:path, name_attribute: true)
28
+ end
29
+
30
+ class ProviderOne < Chef::Provider
31
+ include Poise(inversion: Resource)
32
+ provides(:one)
33
+
34
+ def self.provides_auto?(node, resource)
35
+ true
36
+ end
37
+
38
+ def action_run
39
+ file new_resource.path do
40
+ content 'one'
41
+ end
42
+ end
43
+ end
44
+
45
+ class ProviderTwo < Chef::Provider
46
+ include Poise(inversion: Resource)
47
+ provides(:two)
48
+
49
+ def action_run
50
+ file new_resource.path do
51
+ content 'two'
52
+ end
53
+ end
54
+ end
55
+
56
+ class ProviderThree < Chef::Provider
57
+ include Poise(inversion: Resource)
58
+ provides(:three)
59
+
60
+ def action_run
61
+ file new_resource.path do
62
+ content options['msg'] || 'three'
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,18 @@
1
+ #
2
+ # Copyright 2013-2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ name 'poise_test'
18
+ depends 'poise'
@@ -0,0 +1,25 @@
1
+ #
2
+ # Copyright 2013-2015, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ app '/srv/app' do
18
+ app_config 'defaults' do
19
+ content 'some defaults'
20
+ end
21
+ end
22
+
23
+ app_config 'user' do
24
+ content 'user config'
25
+ end