itamae 1.0.0.beta26 → 1.0.0.beta27

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3ee1b1c898ef9f58d8eb6ad84eae7f28f8b8ae3f
4
- data.tar.gz: e972f58336f252920afc143d310b3e8bf606aed2
3
+ metadata.gz: f71dbe4da1c49cacda9dac2d10c5c1cb0263e6b4
4
+ data.tar.gz: 09480bb0d8624135546598f390cabd30428b8ce0
5
5
  SHA512:
6
- metadata.gz: 6e21652210f37850b32b5ad3171a368844f809ff034d9e9122c01a6d8849629af7990104b99773e0ff35886a96061a0166a6026b4dc8d2200d2feeef5c4f7811
7
- data.tar.gz: 5954033e97e6c554a09809a624b7df553f924d8a63e24224f4dc7146c9867ed4f79a429530b2c8feeef75616511d56ee8115117ecff956bf07b18ccf20797452
6
+ metadata.gz: 4238df2db65e2f9a66d5a0021d724e0e1d1f2234f97b62b4e3fab49f8560e92150124221b2a755f450cf782a919e3ad121ae3a8179021eaeba59eaed9fb08d18
7
+ data.tar.gz: ada64866b96afadc1f916e3a4b106e9e4f59acc8c01e5797e6c86f26988a5b6af207d97de8d09e5ee25816c8e31ad4ad6b49f4abcafe4bbb54395e3c5110ca0f
data/Rakefile CHANGED
@@ -45,6 +45,7 @@ namespace :spec do
45
45
  cmd << " -l #{ENV['LOG_LEVEL'] || 'debug'}"
46
46
  cmd << " -j spec/integration/recipes/node.json"
47
47
  cmd << " spec/integration/recipes/default.rb"
48
+ cmd << " spec/integration/recipes/default2.rb"
48
49
 
49
50
  puts cmd
50
51
  system cmd
data/lib/itamae.rb CHANGED
@@ -3,10 +3,11 @@ require "itamae/runner"
3
3
  require "itamae/cli"
4
4
  require "itamae/recipe"
5
5
  require "itamae/resource"
6
- require "itamae/recipe_dependencies"
6
+ require "itamae/recipe_children"
7
7
  require "itamae/logger"
8
8
  require "itamae/node"
9
9
  require "itamae/backend"
10
+ require "itamae/notification"
10
11
 
11
12
  module Itamae
12
13
  # Your code goes here...
@@ -0,0 +1,23 @@
1
+ require 'itamae'
2
+
3
+ module Itamae
4
+ class Notification < Struct.new(:runner, :defined_in_resource, :action, :target_resource_desc, :timing)
5
+ def resource
6
+ runner.children.find_resource_by_description(target_resource_desc)
7
+ end
8
+
9
+ def run(options)
10
+ action_resource.run(action, options)
11
+ end
12
+
13
+ def action_resource
14
+ resource
15
+ end
16
+ end
17
+
18
+ class Subscription < Notification
19
+ def action_resource
20
+ defined_in_resource
21
+ end
22
+ end
23
+ end
data/lib/itamae/recipe.rb CHANGED
@@ -2,18 +2,20 @@ require 'itamae'
2
2
 
3
3
  module Itamae
4
4
  class Recipe
5
+ NotFoundError = Class.new(StandardError)
6
+
5
7
  attr_reader :path
6
8
  attr_reader :runner
7
- attr_reader :dependencies
8
- attr_reader :delayed_actions
9
+ attr_reader :children
10
+ attr_reader :delayed_notifications
9
11
 
10
12
  def initialize(runner, path)
11
13
  @runner = runner
12
14
  @path = path
13
- @dependencies = RecipeDependencies.new
14
- @delayed_actions = []
15
+ @children = RecipeChildren.new
16
+ @delayed_notifications = []
15
17
 
16
- load_dependencies
18
+ load_children
17
19
  end
18
20
 
19
21
  def node
@@ -21,19 +23,14 @@ module Itamae
21
23
  end
22
24
 
23
25
  def run(options = {})
24
- Logger.info "> Applying recipe... (#{@path})"
25
-
26
- @dependencies.each do |resource|
27
- case resource
28
- when Resource::Base
29
- resource.run(nil, dry_run: options[:dry_run])
30
- when Recipe
31
- resource.run(options)
32
- end
33
- end
26
+ Logger.info "Recipe: #{@path}"
34
27
 
35
- @delayed_actions.uniq.each do |action, resource|
36
- resource.run(action, dry_run: options[:dry_run])
28
+ @children.run(options)
29
+
30
+ @delayed_notifications.uniq do |notification|
31
+ [notification.action, notification.action_resource]
32
+ end.each do |notification|
33
+ notification.run(options)
37
34
  end
38
35
 
39
36
  Logger.info "< Finished. (#{@path})"
@@ -41,22 +38,32 @@ module Itamae
41
38
 
42
39
  private
43
40
 
44
- def load_dependencies
41
+ def load_children
45
42
  instance_eval(File.read(@path), @path, 1)
46
43
  end
47
44
 
48
45
  def method_missing(method, name, &block)
49
46
  klass = Resource.get_resource_class(method)
50
47
  resource = klass.new(self, name, &block)
51
- @dependencies << resource
48
+ @children << resource
52
49
  rescue NameError
53
50
  super
54
51
  end
55
52
 
56
53
  def include_recipe(target)
57
54
  target = ::File.expand_path(target, File.dirname(@path))
55
+
56
+ unless File.exist?(target)
57
+ raise NotFoundError, "File not found. (#{target})"
58
+ end
59
+
60
+ if runner.children.find_recipe_by_path(target)
61
+ Logger.debug "Recipe, #{target}, is skipped because it is already included"
62
+ return
63
+ end
64
+
58
65
  recipe = Recipe.new(@runner, target)
59
- @dependencies << recipe
66
+ @children << recipe
60
67
  end
61
68
  end
62
69
  end
@@ -0,0 +1,61 @@
1
+ module Itamae
2
+ class RecipeChildren < Array
3
+ NotFoundError = Class.new(StandardError)
4
+
5
+ def find_resource_by_description(desc)
6
+ # desc is like 'resource_type[name]'
7
+ resources.find do |resource|
8
+ type, name = Itamae::Resource.parse_description(desc)
9
+ resource.resource_type == type && resource.resource_name == name
10
+ end.tap do |resource|
11
+ unless resource
12
+ raise NotFoundError, "'#{desc}' resource is not found."
13
+ end
14
+ end
15
+ end
16
+
17
+ def subscribing(target)
18
+ resources.map do |resource|
19
+ resource.subscriptions.select do |subscription|
20
+ subscription.resource == target
21
+ end
22
+ end.flatten
23
+ end
24
+
25
+ def find_recipe_by_path(path)
26
+ recipes.find do |recipe|
27
+ recipe.path == path
28
+ end
29
+ end
30
+
31
+ def resources
32
+ self.map do |item|
33
+ case item
34
+ when Resource::Base
35
+ item
36
+ when Recipe
37
+ item.children.resources
38
+ end
39
+ end.flatten
40
+ end
41
+
42
+ def recipes
43
+ self.select do |item|
44
+ item.is_a?(Recipe)
45
+ end.map do |recipe|
46
+ [recipe] + recipe.children.recipes
47
+ end.flatten
48
+ end
49
+
50
+ def run(options)
51
+ self.each do |resource|
52
+ case resource
53
+ when Resource::Base
54
+ resource.run(nil, dry_run: options[:dry_run])
55
+ when Recipe
56
+ resource.run(options)
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -30,14 +30,16 @@ module Itamae
30
30
  attr_reader :resource_name
31
31
  attr_reader :attributes
32
32
  attr_reader :current_attributes
33
+ attr_reader :subscriptions
34
+ attr_reader :notifications
33
35
 
34
36
  def initialize(recipe, resource_name, &block)
35
37
  @attributes = {}
36
38
  @current_attributes = {}
37
39
  @recipe = recipe
38
40
  @resource_name = resource_name
39
- @notifies = []
40
- @subscribes = []
41
+ @notifications = []
42
+ @subscriptions = []
41
43
  @updated = false
42
44
 
43
45
  instance_eval(&block) if block_given?
@@ -46,13 +48,13 @@ module Itamae
46
48
  end
47
49
 
48
50
  def run(specific_action = nil, options = {})
49
- Logger.info "> Executing #{resource_type} (#{attributes})..."
51
+ Logger.info "Executing #{resource_type} (#{attributes})..."
50
52
 
51
53
  if do_not_run_because_of_only_if?
52
- Logger.info "< Execution skipped because of only_if attribute"
54
+ Logger.info "Execution skipped because of only_if attribute"
53
55
  return
54
56
  elsif do_not_run_because_of_not_if?
55
- Logger.info "< Execution skipped because of not_if attribute"
57
+ Logger.info "Execution skipped because of not_if attribute"
56
58
  return
57
59
  end
58
60
 
@@ -69,11 +71,12 @@ module Itamae
69
71
 
70
72
  updated! if different?
71
73
 
72
- notify if updated?
74
+ notify(options) if updated?
73
75
 
74
- Logger.info "< Succeeded."
76
+ Logger.info "Succeeded."
77
+ Logger.info ''
75
78
  rescue Backend::CommandExecutionError
76
- Logger.error "< Failed."
79
+ Logger.error "Failed."
77
80
  exit 2
78
81
  end
79
82
 
@@ -93,21 +96,6 @@ module Itamae
93
96
  humps.join('_')
94
97
  end
95
98
 
96
- def notifies_resources
97
- @notifies.map do |action, resource_desc, timing|
98
- resource = recipe.dependencies.find_by_description(resource_desc)
99
- [action, resource, timing]
100
- end
101
- end
102
-
103
- def subscribes_resources
104
- @subscribes.map do |action, resource_desc, timing|
105
- resource = recipe.dependencies.find_by_description(resource_desc)
106
- [action, resource, timing]
107
- end
108
- end
109
-
110
-
111
99
  private
112
100
 
113
101
  def method_missing(method, *args, &block)
@@ -200,11 +188,11 @@ module Itamae
200
188
  end
201
189
 
202
190
  def notifies(action, resource_desc, timing = :delay)
203
- @notifies << [action, resource_desc, timing]
191
+ @notifications << Notification.new(runner, self, action, resource_desc, timing)
204
192
  end
205
193
 
206
194
  def subscribes(action, resource_desc, timing = :delay)
207
- @subscribes << [action, resource_desc, timing]
195
+ @subscriptions << Subscription.new(runner, self, action, resource_desc, timing)
208
196
  end
209
197
 
210
198
  def node
@@ -248,14 +236,13 @@ module Itamae
248
236
  @updated
249
237
  end
250
238
 
251
- def notify
252
- action_resource_timing = notifies_resources + recipe.dependencies.subscribing(self)
253
- action_resource_timing.uniq.each do |action, resource, timing|
254
- case timing
239
+ def notify(options)
240
+ (notifications + recipe.children.subscribing(self)).each do |notification|
241
+ case notification.timing
255
242
  when :immediately
256
- resource.run(action)
243
+ notification.run(options)
257
244
  when :delay
258
- @recipe.delayed_actions << [action, resource]
245
+ @recipe.delayed_notifications << notification
259
246
  end
260
247
  end
261
248
  end
data/lib/itamae/runner.rb CHANGED
@@ -10,11 +10,8 @@ module Itamae
10
10
  set_backend_from_options(backend_type, options)
11
11
 
12
12
  runner = self.new(node_from_options(options))
13
-
14
- recipe_files.each do |path|
15
- recipe = Recipe.new(runner, File.expand_path(path))
16
- recipe.run(dry_run: options[:dry_run])
17
- end
13
+ runner.load_recipes(recipe_files)
14
+ runner.run(dry_run: options[:dry_run])
18
15
  end
19
16
 
20
17
  private
@@ -60,14 +57,26 @@ module Itamae
60
57
 
61
58
  attr_accessor :node
62
59
  attr_accessor :tmpdir
60
+ attr_accessor :children
63
61
 
64
62
  def initialize(node)
65
63
  @node = node
66
64
  @tmpdir = "/tmp/itamae_tmp"
65
+ @children = RecipeChildren.new
67
66
 
68
67
  Backend.instance.run_command(["mkdir", "-p", @tmpdir])
69
68
  Backend.instance.run_command(["chmod", "777", @tmpdir])
70
69
  end
70
+
71
+ def load_recipes(paths)
72
+ paths.each do |path|
73
+ children << Recipe.new(self, File.expand_path(path))
74
+ end
75
+ end
76
+
77
+ def run(options)
78
+ children.run(options)
79
+ end
71
80
  end
72
81
  end
73
82
 
@@ -1 +1 @@
1
- 1.0.0.beta26
1
+ 1.0.0.beta27
@@ -93,3 +93,7 @@ describe file('/tmp/created_by_itamae_user') do
93
93
  it { should be_owned_by 'itamae' }
94
94
  end
95
95
 
96
+ describe file('/tmp/created_in_default2') do
97
+ it { should be_file }
98
+ end
99
+
@@ -152,3 +152,9 @@ execute "echo Hello > /tmp/created_by_itamae_user" do
152
152
  user "itamae"
153
153
  end
154
154
 
155
+ #####
156
+
157
+ execute "echo 'notify to resource in default2.rb'" do
158
+ notifies :create, "file[put file in default2.rb]"
159
+ end
160
+
@@ -0,0 +1,6 @@
1
+ file "put file in default2.rb" do
2
+ action :nothing
3
+ path "/tmp/created_in_default2"
4
+ content 'Hello'
5
+ end
6
+
@@ -16,6 +16,7 @@ module Itamae
16
16
  describe ".run" do
17
17
  let(:recipes) { %w! ./recipe1.rb ./recipe2.rb ! }
18
18
  it "runs each recipe with the runner" do
19
+ pending "Rewrite later"
19
20
  recipes.each do |r|
20
21
  recipe = double(:recipe)
21
22
  Recipe.stub(:new).with(
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: itamae
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta26
4
+ version: 1.0.0.beta27
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryota Arai
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-22 00:00:00.000000000 Z
11
+ date: 2014-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -158,8 +158,9 @@ files:
158
158
  - lib/itamae/cli.rb
159
159
  - lib/itamae/logger.rb
160
160
  - lib/itamae/node.rb
161
+ - lib/itamae/notification.rb
161
162
  - lib/itamae/recipe.rb
162
- - lib/itamae/recipe_dependencies.rb
163
+ - lib/itamae/recipe_children.rb
163
164
  - lib/itamae/resource.rb
164
165
  - lib/itamae/resource/base.rb
165
166
  - lib/itamae/resource/directory.rb
@@ -180,6 +181,7 @@ files:
180
181
  - spec/integration/Vagrantfile
181
182
  - spec/integration/default_spec.rb
182
183
  - spec/integration/recipes/default.rb
184
+ - spec/integration/recipes/default2.rb
183
185
  - spec/integration/recipes/hello.erb
184
186
  - spec/integration/recipes/hello.txt
185
187
  - spec/integration/recipes/included.rb
@@ -221,6 +223,7 @@ test_files:
221
223
  - spec/integration/Vagrantfile
222
224
  - spec/integration/default_spec.rb
223
225
  - spec/integration/recipes/default.rb
226
+ - spec/integration/recipes/default2.rb
224
227
  - spec/integration/recipes/hello.erb
225
228
  - spec/integration/recipes/hello.txt
226
229
  - spec/integration/recipes/included.rb
@@ -1,39 +0,0 @@
1
- module Itamae
2
- class RecipeDependencies < Array
3
- NotFoundError = Class.new(StandardError)
4
-
5
- def find_by_description(desc)
6
- # desc is like 'resource_type[name]'
7
- resources.find do |resource|
8
- type, name = Itamae::Resource.parse_description(desc)
9
- resource.resource_type == type && resource.resource_name == name
10
- end.tap do |resource|
11
- unless resource
12
- raise NotFoundError, "'#{desc}' resource is not found."
13
- end
14
- end
15
- end
16
-
17
- def subscribing(target)
18
- resources.map do |resource|
19
- resource.subscribes_resources.map do |action, r, timing|
20
- if r == target
21
- [action, resource, timing]
22
- end
23
- end.compact
24
- end.flatten(1)
25
- end
26
-
27
- def resources
28
- self.select do |item|
29
- item.is_a?(Resource::Base)
30
- end
31
- end
32
-
33
- def recipes
34
- self.select do |item|
35
- item.is_a?(Recipe)
36
- end
37
- end
38
- end
39
- end