chef-cookie_cutter 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2d45998bf26c11743232d78a95b91bf8c7259dae
4
+ data.tar.gz: 9ebc37cde72d556674e004f67a6762fd3d5e0f22
5
+ SHA512:
6
+ metadata.gz: 3817bcbd6b32903a9fd086ad2f64cf932bef86d9d5d58978d8619e9b6101cf3c066d9fbe0a043b025f4b2e2ed9d8efa6977e90a306d6ffdd9a359c1afa8b2243
7
+ data.tar.gz: 6554d61d3d4bd5e37375a0b389550e75a1145c720ee26d98fe2ce4ee59d22c426e403668199a08fb636baa7e41eb26c287951d64d9db441bf27d26396a9d23d9
@@ -0,0 +1,96 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright 2015, Ole Claussen <claussen.ole@gmail.com>
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
+ require 'chef/property'
18
+
19
+ class Chef
20
+ module CookieCutter
21
+ class FancyProperty < ::Chef::Property
22
+ def call(resource, *args, **kwargs, &blk)
23
+ return get(resource) if args.empty? && kwargs.empty?
24
+ set(resource, *args, **kwargs, &blk)
25
+ end
26
+
27
+ def get(resource)
28
+ if instance_variable_name && collect? && !is_set?(resource)
29
+ []
30
+ else
31
+ super
32
+ end
33
+ end
34
+
35
+ def set(resource, *args, **kwargs, &blk)
36
+ if args[0].is_a?(DelayedEvaluator)
37
+ set_value(resource, args[0])
38
+ else
39
+ value = coerce(resource, *args, **kwargs, &blk)
40
+ validate(resource, value)
41
+ set_value(resource, value)
42
+ end
43
+ end
44
+
45
+ def coerce(resource, *args, **kwargs, &blk)
46
+ if options.key?(:coerce_class)
47
+ value = options[:coerce_class].new(*args, **kwargs)
48
+ value.instance_eval(&blk) if block_given?
49
+ value
50
+ elsif options.key?(:coerce)
51
+ value = resource.instance_exec(*args, **kwargs, &options[:coerce]) unless resource.nil?
52
+ value.instance_eval(&blk) if block_given?
53
+ value = coerce(resource, value) if value.is_a?(DelayedEvaluator)
54
+ value
55
+ elsif args.length == 1 && kwargs.empty?
56
+ args[0]
57
+ else
58
+ fail Chef::Exceptions::ValidationFailed, "No coercion given for arguments #{args}, #{kwargs}"
59
+ end
60
+ end
61
+
62
+ def emit_dsl
63
+ return unless instance_variable_name
64
+ # Holy shit, this looks evil. But Chef does it the same way so yeah.
65
+ declared_in.class_eval <<-EOM, __FILE__, __LINE__ + 1
66
+ def #{name}(*args, **kwargs, &blk)
67
+ self.class.properties[#{name.inspect}].call(self, *args, **kwargs, &blk)
68
+ end
69
+ EOM
70
+ end
71
+
72
+ def collect?
73
+ options[:collect]
74
+ end
75
+
76
+ def validation_options
77
+ @validation_options ||= options.reject do |k, _|
78
+ [
79
+ :declared_in, :name, :instance_variable_name, :desired_state,
80
+ :identity, :default, :name_property, :coerce, :required, :collect,
81
+ :coerce_class
82
+ ].include?(k)
83
+ end
84
+ end
85
+
86
+ def set_value(resource, value)
87
+ if instance_variable_name && collect?
88
+ resource.instance_variable_set(instance_variable_name, []) unless is_set?(resource)
89
+ get_value(resource) << value
90
+ else
91
+ super
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,63 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright 2015, Ole Claussen <claussen.ole@gmail.com>
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
+ class Chef
19
+ module CookieCutter
20
+ module LWRPInclude
21
+ module_function
22
+
23
+ def filename_for_record(run_context, cookbook_name, segment, name)
24
+ name += '.rb' unless name.end_with?('.rb')
25
+ cookbook_version = run_context.cookbook_collection[cookbook_name]
26
+ file_vendor = ::Chef::Cookbook::FileVendor.create_from_manifest(cookbook_version.manifest)
27
+ manifest_record = cookbook_version.preferred_manifest_record(run_context.node, segment.to_s, name)
28
+ file_vendor.get_filename(manifest_record[:path])
29
+ end
30
+
31
+ def build_resource_module_from_file(filename)
32
+ fail IOError, "Cannot open or read #{filename}" unless File.exist?(filename) && File.readable?(filename)
33
+
34
+ resource_module = Module.new
35
+ resource_module.instance_variable_set('@filename', filename)
36
+ def resource_module.included(cls)
37
+ cls.class_eval(IO.read(@filename), @filename, 1)
38
+ end
39
+ resource_module
40
+ end
41
+ end
42
+
43
+ module ResourceDSL
44
+ def lwrp_include(name, cookbook: nil)
45
+ util_class = ::Chef::CookieCutter::LWRPInclude
46
+ cookbook = lwrp_cookbook_name if cookbook.nil?
47
+ context = lwrp_run_context
48
+ filename = util_class.filename_for_record(context, cookbook, :resources, name)
49
+ include util_class.build_resource_module_from_file(filename)
50
+ end
51
+ end
52
+
53
+ module ProviderDSL
54
+ def lwrp_include(name, cookbook: nil)
55
+ util_class = ::Chef::CookieCutter::LWRPInclude
56
+ cookbook = lwrp_cookbook_name if cookbook.nil?
57
+ context = lwrp_run_context
58
+ filename = util_class.filename_for_record(context, cookbook, :providers, name)
59
+ include util_class.build_resource_module_from_file(filename)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,62 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright 2015, Ole Claussen <claussen.ole@gmail.com>
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
+ class Chef
19
+ module CookieCutter
20
+ module MonkeyPatches
21
+ # Monkey Patches for Chef::Resource::LWRPBase
22
+ # Makes the parameters of build_from_file (i.e. cookbook_name, filename
23
+ # and run_context) available in the created class.
24
+ module LWRPResource
25
+ module ClassMethods
26
+ def build_from_file(cookbook_name, filename, run_context)
27
+ define_singleton_method(:lwrp_cookbook_name) { cookbook_name }
28
+ define_singleton_method(:lwrp_filename) { filename }
29
+ define_singleton_method(:lwrp_run_context) { run_context }
30
+ super
31
+ end
32
+ end
33
+
34
+ def self.prepended(base)
35
+ class << base
36
+ prepend ClassMethods
37
+ end
38
+ end
39
+ end
40
+
41
+ # Monkey Patches for Chef::Provider::LWRPBase
42
+ # Makes the parameters of build_from_file (i.e. cookbook_name, filename
43
+ # and run_context) available in the created class.
44
+ module LWRPProvider
45
+ module ClassMethods
46
+ def build_from_file(cookbook_name, filename, run_context)
47
+ define_singleton_method(:lwrp_cookbook_name) { cookbook_name }
48
+ define_singleton_method(:lwrp_filename) { filename }
49
+ define_singleton_method(:lwrp_run_context) { run_context }
50
+ super
51
+ end
52
+ end
53
+
54
+ def self.prepended(base)
55
+ class << base
56
+ prepend ClassMethods
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,86 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright 2015, Ole Claussen <claussen.ole@gmail.com>
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
+ class Chef
19
+ module CookieCutter
20
+ module Namespace
21
+ module_function
22
+
23
+ class AttributeDoesNotExistError < StandardError
24
+ def initialize(keys, key)
25
+ super <<-EOH
26
+ No attribute `node#{keys.map { |k| "['#{k}']" }.join}' exists on the current
27
+ node. Specifically the `#{key}' attribute is not defined. Please make sure you
28
+ have spelled everything
29
+ correctly.
30
+ EOH
31
+ end
32
+ end
33
+
34
+ def deep_fetch(attributes, keys)
35
+ keys.map!(&:to_s)
36
+ keys.inject(attributes.to_hash) do |hash, key|
37
+ if hash.key?(key)
38
+ hash[key]
39
+ else
40
+ fail ::Chef::CookieCutter::Namespace::AttributeDoesNotExistError.new(keys, key)
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ module DSL
47
+ def namespace(*args)
48
+ keys = args.map(&:to_s)
49
+ attribute = ::Chef::CookieCutter::Namespace.deep_fetch(node.attributes, keys)
50
+ yield attribute if block_given?
51
+ end
52
+ end
53
+ end
54
+
55
+ class Node
56
+ def namespace(*args, **kwargs, &blk)
57
+ @namespace_options ||= { precedence: default }
58
+ @namespace_options = @namespace_options.merge(kwargs)
59
+ keys = args.map(&:to_s)
60
+ @current_namespace ||= []
61
+ @current_namespace += keys
62
+ instance_eval(&blk) if block_given?
63
+ @current_namespace -= keys
64
+ @namespace_options = nil if @current_namespace.empty?
65
+ nil
66
+ end
67
+
68
+ def method_missing(method_name, *args)
69
+ attributes.send(method_name, *args)
70
+ rescue NoMethodError
71
+ @current_namespace ||= []
72
+ @namespace_options ||= { precedence: default }
73
+ if args.empty?
74
+ deep_key = @current_namespace.dup << method_name.to_s
75
+ return ::Chef::CookieCutter::Namespace.deep_fetch!(attributes, deep_key)
76
+ else
77
+ vivified = @current_namespace.inject(@namespace_options[:precedence]) do |hash, item|
78
+ hash[item] ||= {}
79
+ hash[item]
80
+ end
81
+ vivified[method_name.to_s] = args.size == 1 ? args.first : args
82
+ return nil
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright 2015, Ole Claussen <claussen.ole@gmail.com>
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
+ class Chef
19
+ module CookieCutter
20
+ module RunState
21
+ module_function
22
+
23
+ class RunStateDoesNotExistError < StandardError
24
+ def initialize(keys, key)
25
+ hash = keys.map { |k| "['#{k}']" }
26
+ super <<-EOH
27
+ The run_state does not contain an element at run_state#{hash.join}.
28
+ Specifically, #{key} is not defined.
29
+ EOH
30
+ end
31
+ end
32
+
33
+ def store_state(node, *subkeys, key, value)
34
+ subkeys.map!(&:to_s)
35
+ hash = node.run_state
36
+ subkeys.each do |k|
37
+ hash[k] = {} if hash[k].nil?
38
+ hash = hash[k]
39
+ end
40
+ hash[key.to_s] = value
41
+ end
42
+
43
+ def fetch_state(node, *keys)
44
+ keys.map!(&:to_s)
45
+ keys.inject(node.run_state) do |hash, key|
46
+ fail ::Chef::CookieCutter::RunState::RunStateDoesNotExistError.new(keys, key) unless hash.key? key
47
+ hash[key]
48
+ end
49
+ end
50
+ end
51
+
52
+ module DSL
53
+ def store_state(*subkeys, key, value)
54
+ ::Chef::CookieCutter::RunState.store_state(node, *subkeys, key, value)
55
+ end
56
+
57
+ def fetch_state(*keys)
58
+ ::Chef::CookieCutter::RunState.fetch_state(node, *keys)
59
+ end
60
+
61
+ def exist_state?(*keys)
62
+ ::Chef::CookieCutter::RunState.fetch_state(node, *keys)
63
+ true
64
+ rescue ::Chef::CookieCutter::RunState::RunStateDoesNotExistError
65
+ false
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,58 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright 2015, Ole Claussen <claussen.ole@gmail.com>
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
+ class Chef
19
+ module CookieCutter
20
+ module SharedBlocks
21
+ module_function
22
+
23
+ class SharedBlockAlreadyDefined < StandardError
24
+ def initialize(name)
25
+ super <<-EOH
26
+ A shared block with the name #{name} already exists. Please make sure that
27
+ every shared block you define has a unique name.
28
+ EOH
29
+ end
30
+ end
31
+
32
+ class SharedBlockNotDefined < StandardError
33
+ def initialize(name)
34
+ super <<-EOH
35
+ The shared block with the name #{name} is not defined.
36
+ EOH
37
+ end
38
+ end
39
+ end
40
+
41
+ module DSL
42
+ def shared?(name)
43
+ exist_state?(:dotfiles, :shared_blocks, name)
44
+ end
45
+
46
+ def shared(name, &block)
47
+ fail Chef::CookieCutter::SharedBlocks::SharedBlockAlreadyDefined, name if shared? name
48
+ store_state(:dotfiles, :shared_blocks, name, block)
49
+ end
50
+
51
+ def include_shared(name)
52
+ fail Chef::CookieCutter::SharedBlocks::SharedBlockNotDefined, name unless shared? name
53
+ block = fetch_state(:dotfiles, :shared_blocks, name)
54
+ instance_eval(&block)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,50 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright 2015, Ole Claussen <claussen.ole@gmail.com>
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
+ require 'chef/recipe'
18
+ require 'chef/resource'
19
+ require 'chef/resource/lwrp_base'
20
+ require 'chef/provider'
21
+ require 'chef/provider/lwrp_base'
22
+
23
+ class Chef
24
+ module CookieCutter
25
+ def self.chef_version(version)
26
+ ::Gem::Requirement.new(version).satisfied_by?(::Gem::Version.new(::Chef::VERSION))
27
+ end
28
+
29
+ if chef_version('~> 12.5.0.alpha')
30
+ require_relative 'cookie_cutter/fancy_property'
31
+ end
32
+
33
+ require_relative 'cookie_cutter/lwrp_include'
34
+ require_relative 'cookie_cutter/monkey_patches'
35
+ require_relative 'cookie_cutter/namespace'
36
+ require_relative 'cookie_cutter/run_state'
37
+ require_relative 'cookie_cutter/shared_blocks'
38
+ end
39
+ end
40
+
41
+ # Register Monkey Patches
42
+ Chef::Resource::LWRPBase.send(:prepend, Chef::CookieCutter::MonkeyPatches::LWRPResource)
43
+ Chef::Provider::LWRPBase.send(:prepend, Chef::CookieCutter::MonkeyPatches::LWRPProvider)
44
+
45
+ # Register DSL
46
+ Chef::Recipe.send(:include, Chef::CookieCutter::DSL)
47
+ Chef::Resource.send(:include, Chef::CookieCutter::DSL)
48
+ Chef::Provider.send(:include, Chef::CookieCutter::DSL)
49
+ Chef::Resource::LWRPBase.send(:extend, Chef::CookieCutter::ResourceDSL)
50
+ Chef::Provider::LWRPBase.send(:extend, Chef::CookieCutter::ProviderDSL)
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chef-cookie_cutter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ole Claussen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: chef
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: A small collection of Chef hacks and workarounds.
70
+ email: claussen.ole@gmail.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - lib/chef/cookie_cutter.rb
76
+ - lib/chef/cookie_cutter/fancy_property.rb
77
+ - lib/chef/cookie_cutter/lwrp_include.rb
78
+ - lib/chef/cookie_cutter/monkey_patches.rb
79
+ - lib/chef/cookie_cutter/namespace.rb
80
+ - lib/chef/cookie_cutter/run_state.rb
81
+ - lib/chef/cookie_cutter/shared_blocks.rb
82
+ homepage: https://github.com/oclaussen/chef-cookie-cutter
83
+ licenses:
84
+ - Apache 2.0
85
+ metadata: {}
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '2.0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubyforge_project:
102
+ rubygems_version: 2.4.5
103
+ signing_key:
104
+ specification_version: 4
105
+ summary: A small collection of Chef hacks and workarounds.
106
+ test_files: []