knife-spork 1.7.2 → 1.7.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +35 -35
  3. data/lib/chef/knife/spork-bump.rb +100 -100
  4. data/lib/chef/knife/spork-check.rb +165 -161
  5. data/lib/chef/knife/spork-databag-create.rb +54 -54
  6. data/lib/chef/knife/spork-databag-delete.rb +51 -51
  7. data/lib/chef/knife/spork-databag-edit.rb +54 -54
  8. data/lib/chef/knife/spork-databag-fromfile.rb +88 -88
  9. data/lib/chef/knife/spork-delete.rb +132 -132
  10. data/lib/chef/knife/spork-environment-check.rb +90 -90
  11. data/lib/chef/knife/spork-environment-create.rb +63 -63
  12. data/lib/chef/knife/spork-environment-delete.rb +38 -38
  13. data/lib/chef/knife/spork-environment-edit.rb +40 -40
  14. data/lib/chef/knife/spork-environment-fromfile.rb +46 -46
  15. data/lib/chef/knife/spork-info.rb +34 -34
  16. data/lib/chef/knife/spork-node-create.rb +41 -41
  17. data/lib/chef/knife/spork-node-delete.rb +41 -41
  18. data/lib/chef/knife/spork-node-edit.rb +48 -48
  19. data/lib/chef/knife/spork-node-fromfile.rb +46 -46
  20. data/lib/chef/knife/spork-node-runlistadd.rb +51 -51
  21. data/lib/chef/knife/spork-node-runlistremove.rb +44 -44
  22. data/lib/chef/knife/spork-node-runlistset.rb +44 -44
  23. data/lib/chef/knife/spork-omni.rb +112 -112
  24. data/lib/chef/knife/spork-promote.rb +197 -197
  25. data/lib/chef/knife/spork-role-create.rb +46 -46
  26. data/lib/chef/knife/spork-role-delete.rb +50 -50
  27. data/lib/chef/knife/spork-role-edit.rb +40 -40
  28. data/lib/chef/knife/spork-role-fromfile.rb +65 -65
  29. data/lib/chef/knife/spork-upload.rb +151 -151
  30. data/lib/chef/knife/spork-version.rb +12 -12
  31. data/lib/knife-spork.rb +3 -3
  32. data/lib/knife-spork/plugins.rb +27 -27
  33. data/lib/knife-spork/plugins/campfire.rb +219 -219
  34. data/lib/knife-spork/plugins/eventinator.rb +329 -329
  35. data/lib/knife-spork/plugins/foodcritic.rb +46 -46
  36. data/lib/knife-spork/plugins/git.rb +393 -399
  37. data/lib/knife-spork/plugins/graphite.rb +25 -25
  38. data/lib/knife-spork/plugins/grove.rb +167 -167
  39. data/lib/knife-spork/plugins/hipchat.rb +171 -171
  40. data/lib/knife-spork/plugins/influxdb.rb +28 -28
  41. data/lib/knife-spork/plugins/irccat.rb +332 -332
  42. data/lib/knife-spork/plugins/jabber.rb +133 -133
  43. data/lib/knife-spork/plugins/plugin.rb +117 -117
  44. data/lib/knife-spork/plugins/rubocop.rb +56 -56
  45. data/lib/knife-spork/plugins/slack.rb +125 -125
  46. data/lib/knife-spork/plugins/statusnet.rb +122 -122
  47. data/lib/knife-spork/runner.rb +342 -342
  48. data/lib/knife-spork/version.rb +5 -5
  49. metadata +4 -51
  50. data/.gitignore +0 -21
  51. data/.ruby-gemset +0 -1
  52. data/.ruby-version +0 -1
  53. data/.travis.yml +0 -3
  54. data/CHANGELOG.md +0 -445
  55. data/Gemfile +0 -3
  56. data/README.md +0 -544
  57. data/Rakefile +0 -35
  58. data/knife-spork.gemspec +0 -28
  59. data/plugins/Campfire.md +0 -43
  60. data/plugins/Eventinator.md +0 -30
  61. data/plugins/Foodcritic.md +0 -53
  62. data/plugins/Git.md +0 -53
  63. data/plugins/Graphite.md +0 -30
  64. data/plugins/Grove.md +0 -31
  65. data/plugins/HipChat.md +0 -69
  66. data/plugins/Influxdb.md +0 -25
  67. data/plugins/Irccat.md +0 -50
  68. data/plugins/Jabber.md +0 -61
  69. data/plugins/README.md +0 -70
  70. data/plugins/Rubocop.md +0 -110
  71. data/plugins/Slack.md +0 -48
  72. data/plugins/StatusNet.md +0 -41
  73. data/plugins/Template.md +0 -34
  74. data/spec/spec_helper.rb +0 -10
  75. data/spec/test_helpers.rb +0 -46
  76. data/spec/unit/fixtures/config/spork-config.yml +0 -1
  77. data/spec/unit/fixtures/cookbooks/example/metadata.rb +0 -8
  78. data/spec/unit/fixtures/environments/example.json +0 -12
  79. data/spec/unit/fixtures/knife.rb +0 -6
  80. data/spec/unit/fixtures/test_client.pem +0 -27
  81. data/spec/unit/spork_bump_spec.rb +0 -75
  82. data/spec/unit/spork_info_spec.rb +0 -40
  83. data/spec/unit/spork_promote_spec.rb +0 -77
  84. data/spec/unit/spork_upload_spec.rb +0 -46
@@ -1,46 +1,46 @@
1
- require 'knife-spork/plugins/plugin'
2
-
3
- module KnifeSpork
4
- module Plugins
5
- class Foodcritic < Plugin
6
- name :foodcritic
7
- hooks :after_check, :before_upload
8
-
9
- def perform
10
- safe_require 'foodcritic'
11
-
12
- if Gem::Specification.find_all_by_name("foodcritic", ">= 3.0.0").empty?
13
- ui.fatal "The knife-spork foodcritic plugin requires foodcritic >= 3.0.0. Please install a more recent foodcritic version."
14
- exit 1
15
- end
16
-
17
- tags = config.tags || []
18
- fail_tags = config.fail_tags || ['any']
19
- include_rules = config.include_rules || []
20
-
21
- cookbooks.each do |cookbook|
22
- ui.info "Running foodcritic against #{cookbook.name}@#{cookbook.version}..."
23
-
24
- cookbook_path = cookbook.root_dir
25
-
26
- ui.info cookbook_path
27
-
28
- options = {:tags => tags, :fail_tags => fail_tags, :include_rules => include_rules, :cookbook_paths => [cookbook_path]}
29
- review = ::FoodCritic::Linter.new.check(options)
30
-
31
- if review.failed?
32
- ui.error "Foodcritic failed!"
33
- review.to_s.split("\n").each{ |r| ui.error r.to_s }
34
- exit(1) if config.epic_fail
35
- else
36
- ui.info "Passed!"
37
- end
38
- end
39
- end
40
-
41
- def epic_fail?
42
- config.epic_fail.nil? ? 'true' : config.epic_fail
43
- end
44
- end
45
- end
46
- end
1
+ require 'knife-spork/plugins/plugin'
2
+
3
+ module KnifeSpork
4
+ module Plugins
5
+ class Foodcritic < Plugin
6
+ name :foodcritic
7
+ hooks :after_check, :before_upload
8
+
9
+ def perform
10
+ safe_require 'foodcritic'
11
+
12
+ if Gem::Specification.find_all_by_name("foodcritic", ">= 3.0.0").empty?
13
+ ui.fatal "The knife-spork foodcritic plugin requires foodcritic >= 3.0.0. Please install a more recent foodcritic version."
14
+ exit 1
15
+ end
16
+
17
+ tags = config.tags || []
18
+ fail_tags = config.fail_tags || ['any']
19
+ include_rules = config.include_rules || []
20
+
21
+ cookbooks.each do |cookbook|
22
+ ui.info "Running foodcritic against #{cookbook.name}@#{cookbook.version}..."
23
+
24
+ cookbook_path = cookbook.root_dir
25
+
26
+ ui.info cookbook_path
27
+
28
+ options = {:tags => tags, :fail_tags => fail_tags, :include_rules => include_rules, :cookbook_paths => [cookbook_path]}
29
+ review = ::FoodCritic::Linter.new.check(options)
30
+
31
+ if review.failed?
32
+ ui.error "Foodcritic failed!"
33
+ review.to_s.split("\n").each{ |r| ui.error r.to_s }
34
+ exit(1) if config.epic_fail
35
+ else
36
+ ui.info "Passed!"
37
+ end
38
+ end
39
+ end
40
+
41
+ def epic_fail?
42
+ config.epic_fail.nil? ? 'true' : config.epic_fail
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,399 +1,393 @@
1
- require 'knife-spork/plugins/plugin'
2
-
3
- module KnifeSpork
4
- module Plugins
5
- class Git < Plugin
6
- name :git
7
-
8
- def perform; end
9
-
10
- # Role Git wrappers
11
- def before_rolecreate
12
- if config.auto_push
13
- if !File.directory?(role_path)
14
- ui.error "Role path #{role_path} does not exist"
15
- exit 1
16
- end
17
- git_pull(role_path)
18
- if File.exist?(File.join(role_path, object_name + '.json'))
19
- ui.error 'Role already exists in local git, aborting creation'
20
- exit 1
21
- end
22
- end
23
- end
24
- def after_rolecreate
25
- if config.auto_push
26
- if !File.directory?(role_path)
27
- ui.error "Role path #{role_path} does not exist"
28
- exit 1
29
- end
30
- save_role(object_name) unless object_difference == ''
31
- end
32
- end
33
- def before_roleedit
34
- if config.auto_push
35
- git_pull(role_path)
36
- if !File.exist?(File.join(role_path, object_name + '.json'))
37
- ui.error 'Role does not exist in git, please create it first with spork'
38
- exit 1
39
- end
40
- end
41
- end
42
- def after_roleedit
43
- if config.auto_push
44
- save_role(object_name) unless object_difference == ''
45
- end
46
- end
47
- def before_roledelete
48
- if config.auto_push
49
- git_pull(role_path)
50
- end
51
- end
52
- def after_roledelete
53
- if config.auto_push
54
- delete_role(object_name)
55
- end
56
- end
57
-
58
- # Environmental Git wrappers
59
- def before_environmentcreate
60
- if config.auto_push
61
- if !File.directory?(environment_path)
62
- ui.error "Environment path #{environment_path} does not exist"
63
- exit 1
64
- end
65
- git_pull(environment_path)
66
- if File.exist?(File.join(environment_path, object_name + '.json'))
67
- ui.error 'Environment already exists in local git, aborting creation'
68
- exit 1
69
- end
70
- end
71
- end
72
- def after_environmentcreate
73
- if config.auto_push
74
- save_environment(object_name) unless object_difference == ''
75
- end
76
- end
77
- def before_environmentedit
78
- if config.auto_push
79
- git_pull(environment_path)
80
- if !File.exist?(File.join(environment_path, object_name + '.json'))
81
- ui.error 'Environment does not exist in git, please create it first with spork'
82
- exit 1
83
- end
84
- end
85
- end
86
- def after_environmentedit
87
- if config.auto_push
88
- save_environment(object_name) unless object_difference == ''
89
- end
90
- end
91
- def before_environmentdelete
92
- if config.auto_push
93
- git_pull(environment_path)
94
- end
95
- end
96
- def after_environmentdelete
97
- if config.auto_push
98
- delete_environment(object_name)
99
- end
100
- end
101
-
102
- # Node Git wrappers
103
- def before_nodecreate
104
- if config.auto_push
105
- git_pull(node_path)
106
- if File.exist?(File.join(node_path, object_name + '.json'))
107
- ui.error 'Node already exists in local git, aborting creation'
108
- exit 1
109
- end
110
- end
111
- end
112
- def after_nodecreate
113
- if config.auto_push
114
- save_node(object_name) unless object_difference == ''
115
- end
116
- end
117
- def before_nodeedit
118
- if config.auto_push
119
- git_pull(node_path)
120
- if !File.exist?(File.join(node_path, object_name + '.json'))
121
- ui.error 'Node does not exist in git, please bootstrap one first'
122
- exit 1
123
- end
124
- end
125
- end
126
- def after_nodeedit
127
- if config.auto_push
128
- save_node(object_name) unless object_difference == ''
129
- end
130
- end
131
- def before_nodedelete
132
- if config.auto_push
133
- git_pull(node_path)
134
- end
135
- end
136
- def after_nodedelete
137
- if config.auto_push
138
- delete_node(object_name)
139
- end
140
- end
141
-
142
- def before_bump
143
- git_pull(environment_path) unless cookbook_path.include?(environment_path.gsub"/environments","")
144
- git_pull_submodules(environment_path) unless cookbook_path.include?(environment_path.gsub"/environments","")
145
- cookbooks.each do |cookbook|
146
- git_pull(cookbook_path_for(cookbook))
147
- git_pull_submodules(cookbook_path_for(cookbook))
148
- end
149
- end
150
-
151
- def before_upload
152
- git_pull(environment_path) unless cookbook_path.include?(environment_path.gsub"/environments","")
153
- git_pull_submodules(environment_path) unless cookbook_path.include?(environment_path.gsub"/environments","")
154
- cookbooks.each do |cookbook|
155
- git_pull(cookbook_path_for(cookbook))
156
- git_pull_submodules(cookbook_path_for(cookbook))
157
- end
158
- end
159
-
160
- def before_promote
161
- cookbooks.each do |cookbook|
162
- git_pull(environment_path) unless cookbook_path_for(cookbook).include?(environment_path.gsub"/environments","")
163
- git_pull_submodules(environment_path) unless cookbook_path_for(cookbook).include?(environment_path.gsub"/environments","")
164
- git_pull(cookbook_path_for(cookbook))
165
- git_pull_submodules(cookbook_path_for(cookbook))
166
- end
167
- end
168
-
169
- def after_bump
170
- cookbooks.each do |cookbook|
171
- git_add(cookbook_path_for(cookbook),"metadata.rb")
172
- end
173
- end
174
-
175
- def after_promote_local
176
- environments.each do |environment|
177
- git_add(environment_path,"#{environment}.json")
178
- end
179
- if config.auto_push
180
- branch = if not config.branch.nil?
181
- config[:branch]
182
- else
183
- "master"
184
- end
185
-
186
- git_commit(environment_path, "promote #{cookbooks.collect{ |c| "#{c.name}@#{c.version}" }.join(",")} to #{environments.join(",")}")
187
- git_push(branch)
188
- end
189
- end
190
-
191
- def save_node(node)
192
- json = JSON.pretty_generate(Chef::Node.load(node))
193
- node_file = File.expand_path( File.join(node_path, "#{node}.json") )
194
- File.open(node_file, 'w'){ |f| f.puts(json) }
195
- git_add(node_path, "#{node}.json")
196
- git_commit(node_path, "[NODE] Updated #{node}")
197
- git_push(branch) if config.auto_push
198
- end
199
- def delete_node(node)
200
- git_rm(node_path, "#{node}.json")
201
- git_commit(node_path, "[NODE] Deleted #{node}")
202
- git_push(branch) if config.auto_push
203
- end
204
-
205
- def save_role(role)
206
- json = JSON.pretty_generate(Chef::Role.load(role))
207
- role_file = File.expand_path( File.join(role_path, "#{role}.json") )
208
- File.open(role_file, 'w'){ |f| f.puts(json) }
209
- git_add(role_path, "#{role}.json")
210
- git_commit(role_path, "[ROLE] Updated #{role}")
211
- git_push(branch)
212
- end
213
- def delete_role(role)
214
- git_rm(role_path, "#{role}.json")
215
- if config.auto_push
216
- git_commit(role_path, "[ROLE] Deleted #{role}")
217
- git_push(branch)
218
- end
219
- end
220
-
221
- def save_environment(environment)
222
- json = JSON.pretty_generate(Chef::Environment.load(environment))
223
- environment_file = File.expand_path( File.join(environment_path, "#{environment}.json") )
224
- File.open(environment_file, 'w'){ |f| f.puts(json) }
225
- git_add(environment_path, "#{environment}.json")
226
- git_commit(environment_path, "[ENV] Updated #{environment}")
227
- git_push(branch) if config.auto_push
228
- end
229
- def delete_environment(environment)
230
- git_rm(environment_path, "#{environment}.json")
231
- git_commit(environment_path, "[ENV] Deleted #{environment}")
232
- git_push(branch) if config.auto_push
233
- end
234
-
235
- private
236
- def git
237
- safe_require 'git'
238
- log = Logger.new(STDOUT)
239
- log.level = Logger::WARN
240
- @git ||= begin
241
- cwd = FileUtils.pwd()
242
- ::Git.open(get_parent_dir(cwd) , :log => log)
243
- rescue Exception => e
244
- ui.error "You are not currently in a git repository #{cwd}. Please ensure you are in a git repo, a repo subdirectory, or remove the git plugin from your KnifeSpork configuration!"
245
- exit(0)
246
- end
247
- end
248
-
249
- # In this case, a git pull will:
250
- # - Stash local changes
251
- # - Pull from the remote
252
- # - Pop the stash
253
- def git_pull(path)
254
- if is_repo?(path)
255
- ui.msg "Git: Pulling latest changes from #{path}"
256
- output = IO.popen("cd #{path} && git pull 2>&1")
257
- Process.wait
258
- exit_code = $?
259
- if !exit_code.exitstatus == 0
260
- ui.error "#{output.read()}\n"
261
- exit 1
262
- end
263
- end
264
- end
265
-
266
- def git_pull_submodules(path)
267
- if is_repo?(path)
268
- ui.msg "Pulling latest changes from git submodules (if any)"
269
- top_level = `cd #{path} && git rev-parse --show-toplevel 2>&1`.chomp
270
- if is_submodule?(top_level)
271
- top_level = get_parent_dir(top_level)
272
- end
273
- output = IO.popen("cd #{top_level} && git submodule foreach git pull 2>&1")
274
- Process.wait
275
- exit_code = $?
276
- if !exit_code.exitstatus == 0
277
- ui.error "#{output.read()}\n"
278
- exit 1
279
- end
280
- end
281
- end
282
-
283
- def git_add(filepath,filename)
284
- if is_repo?(filepath)
285
- ui.msg "Git add'ing #{filepath}/#{filename}"
286
- output = IO.popen("cd #{filepath} && git add #{filename}")
287
- Process.wait
288
- exit_code = $?
289
- if !exit_code.exitstatus == 0
290
- ui.error "#{output.read()}\n"
291
- exit 1
292
- end
293
- end
294
- end
295
-
296
- def git_commit(filepath, msg)
297
- begin
298
- if is_repo?(filepath)
299
- ui.msg "Git: Committing changes..."
300
- git.commit msg
301
- end
302
- rescue ::Git::GitExecuteError;
303
- end
304
- end
305
-
306
- def git_push(branch)
307
- begin
308
- ui.msg "Git: Pushing to #{branch}"
309
- git.push "origin", branch
310
- rescue ::Git::GitExecuteError => e
311
- ui.error "Could not push to master: #{e.message}"
312
- end
313
- end
314
-
315
- def git_rm(filepath, filename)
316
- if is_repo?(filepath)
317
- ui.msg "Git rm'ing #{filepath}/#{filename}"
318
- output = IO.popen("cd #{filepath} && git rm #{filename}")
319
- Process.wait
320
- exit_code = $?
321
- if !exit_code.exitstatus == 0
322
- ui.error "#{output.read()}\n"
323
- exit 1
324
- end
325
- end
326
- end
327
-
328
- def git_tag(tag)
329
- begin
330
- git.add_tag(tag)
331
- rescue ::Git::GitExecuteError => e
332
- ui.error "Could not tag #{tag_name}. Does it already exist?"
333
- ui.error 'You may need to delete the tag before running promote again.'
334
- end
335
- end
336
-
337
- def is_repo?(path)
338
- output = IO.popen("cd #{path} && git rev-parse --git-dir 2>&1")
339
- Process.wait
340
- if $? != 0
341
- ui.warn "#{path} is not a git repo, skipping..."
342
- return false
343
- else
344
- return true
345
- end
346
- end
347
-
348
- def is_submodule?(path)
349
- top_level = `cd #{path} && git rev-parse --show-toplevel 2>&1`.chomp
350
- output = IO.popen("cd #{top_level}/.. && git rev-parse --show-toplevel 2>&1")
351
- Process.wait
352
- if $? != 0
353
- return false
354
- else
355
- return true
356
- end
357
- end
358
-
359
- def get_parent_dir(path)
360
- top_level = path
361
- return_code = 0
362
- while return_code == 0
363
- output = IO.popen("cd #{top_level}/.. && git rev-parse --show-toplevel 2>&1")
364
- Process.wait
365
- return_code = $?
366
- cmd_output = output.read.chomp
367
- #cygwin, I hate you for making me do this
368
- if cmd_output.include?("fatal: Not a git repository")
369
- return_code = 1
370
- end
371
- if return_code == 0
372
- top_level = cmd_output
373
- end
374
- end
375
- top_level
376
- end
377
-
378
- def remote
379
- config.remote || 'origin'
380
- end
381
-
382
- def branch
383
- config.branch || 'master'
384
- end
385
-
386
- def tag_name
387
- cookbooks.collect{|c| "#{c.name}@#{c.version}"}.join('-')
388
- end
389
-
390
- def cookbook_path_for cookbook
391
- if defined?(Berkshelf) and cookbook.is_a? Berkshelf::CachedCookbook
392
- cookbook.path.to_s
393
- else
394
- cookbook.root_dir
395
- end
396
- end
397
- end
398
- end
399
- end
1
+ require 'knife-spork/plugins/plugin'
2
+
3
+ module KnifeSpork
4
+ module Plugins
5
+ class Git < Plugin
6
+ name :git
7
+
8
+ def perform; end
9
+
10
+ # Role Git wrappers
11
+ def before_rolecreate
12
+ if config.auto_push
13
+ if !File.directory?(role_path)
14
+ ui.error "Role path #{role_path} does not exist"
15
+ exit 1
16
+ end
17
+ git_pull(role_path)
18
+ if File.exist?(File.join(role_path, object_name + '.json'))
19
+ ui.error 'Role already exists in local git, aborting creation'
20
+ exit 1
21
+ end
22
+ end
23
+ end
24
+ def after_rolecreate
25
+ if config.auto_push
26
+ if !File.directory?(role_path)
27
+ ui.error "Role path #{role_path} does not exist"
28
+ exit 1
29
+ end
30
+ save_role(object_name) unless object_difference == ''
31
+ end
32
+ end
33
+ def before_roleedit
34
+ if config.auto_push
35
+ git_pull(role_path)
36
+ if !File.exist?(File.join(role_path, object_name + '.json'))
37
+ ui.error 'Role does not exist in git, please create it first with spork'
38
+ exit 1
39
+ end
40
+ end
41
+ end
42
+ def after_roleedit
43
+ if config.auto_push
44
+ save_role(object_name) unless object_difference == ''
45
+ end
46
+ end
47
+ def before_roledelete
48
+ if config.auto_push
49
+ git_pull(role_path)
50
+ end
51
+ end
52
+ def after_roledelete
53
+ if config.auto_push
54
+ delete_role(object_name)
55
+ end
56
+ end
57
+
58
+ # Environmental Git wrappers
59
+ def before_environmentcreate
60
+ if config.auto_push
61
+ if !File.directory?(environment_path)
62
+ ui.error "Environment path #{environment_path} does not exist"
63
+ exit 1
64
+ end
65
+ git_pull(environment_path)
66
+ if File.exist?(File.join(environment_path, object_name + '.json'))
67
+ ui.error 'Environment already exists in local git, aborting creation'
68
+ exit 1
69
+ end
70
+ end
71
+ end
72
+ def after_environmentcreate
73
+ if config.auto_push
74
+ save_environment(object_name) unless object_difference == ''
75
+ end
76
+ end
77
+ def before_environmentedit
78
+ if config.auto_push
79
+ git_pull(environment_path)
80
+ if !File.exist?(File.join(environment_path, object_name + '.json'))
81
+ ui.error 'Environment does not exist in git, please create it first with spork'
82
+ exit 1
83
+ end
84
+ end
85
+ end
86
+ def after_environmentedit
87
+ if config.auto_push
88
+ save_environment(object_name) unless object_difference == ''
89
+ end
90
+ end
91
+ def before_environmentdelete
92
+ if config.auto_push
93
+ git_pull(environment_path)
94
+ end
95
+ end
96
+ def after_environmentdelete
97
+ if config.auto_push
98
+ delete_environment(object_name)
99
+ end
100
+ end
101
+
102
+ # Node Git wrappers
103
+ def before_nodecreate
104
+ if config.auto_push
105
+ git_pull(node_path)
106
+ if File.exist?(File.join(node_path, object_name + '.json'))
107
+ ui.error 'Node already exists in local git, aborting creation'
108
+ exit 1
109
+ end
110
+ end
111
+ end
112
+ def after_nodecreate
113
+ if config.auto_push
114
+ save_node(object_name) unless object_difference == ''
115
+ end
116
+ end
117
+ def before_nodeedit
118
+ if config.auto_push
119
+ git_pull(node_path)
120
+ if !File.exist?(File.join(node_path, object_name + '.json'))
121
+ ui.error 'Node does not exist in git, please bootstrap one first'
122
+ exit 1
123
+ end
124
+ end
125
+ end
126
+ def after_nodeedit
127
+ if config.auto_push
128
+ save_node(object_name) unless object_difference == ''
129
+ end
130
+ end
131
+ def before_nodedelete
132
+ if config.auto_push
133
+ git_pull(node_path)
134
+ end
135
+ end
136
+ def after_nodedelete
137
+ if config.auto_push
138
+ delete_node(object_name)
139
+ end
140
+ end
141
+
142
+ def before_bump
143
+ git_pull(environment_path) unless cookbook_path.include?(environment_path.gsub"/environments","")
144
+ git_pull_submodules(environment_path) unless cookbook_path.include?(environment_path.gsub"/environments","")
145
+ cookbooks.each do |cookbook|
146
+ git_pull(cookbook_path_for(cookbook))
147
+ git_pull_submodules(cookbook_path_for(cookbook))
148
+ end
149
+ end
150
+
151
+ def before_upload
152
+ git_pull(environment_path) unless cookbook_path.include?(environment_path.gsub"/environments","")
153
+ git_pull_submodules(environment_path) unless cookbook_path.include?(environment_path.gsub"/environments","")
154
+ cookbooks.each do |cookbook|
155
+ git_pull(cookbook_path_for(cookbook))
156
+ git_pull_submodules(cookbook_path_for(cookbook))
157
+ end
158
+ end
159
+
160
+ def before_promote
161
+ cookbooks.each do |cookbook|
162
+ git_pull(environment_path) unless cookbook_path_for(cookbook).include?(environment_path.gsub"/environments","")
163
+ git_pull_submodules(environment_path) unless cookbook_path_for(cookbook).include?(environment_path.gsub"/environments","")
164
+ git_pull(cookbook_path_for(cookbook))
165
+ git_pull_submodules(cookbook_path_for(cookbook))
166
+ end
167
+ end
168
+
169
+ def after_bump
170
+ cookbooks.each do |cookbook|
171
+ git_add(cookbook_path_for(cookbook),"metadata.rb")
172
+ end
173
+ end
174
+
175
+ def after_promote_local
176
+ environments.each do |environment|
177
+ git_add(environment_path,"#{environment}.json")
178
+ end
179
+ if config.auto_push
180
+ git_commit(environment_path, "promote #{cookbooks.collect{ |c| "#{c.name}@#{c.version}" }.join(",")} to #{environments.join(",")}")
181
+ git_push(branch)
182
+ end
183
+ end
184
+
185
+ def save_node(node)
186
+ json = JSON.pretty_generate(Chef::Node.load(node))
187
+ node_file = File.expand_path( File.join(node_path, "#{node}.json") )
188
+ File.open(node_file, 'w'){ |f| f.puts(json) }
189
+ git_add(node_path, "#{node}.json")
190
+ git_commit(node_path, "[NODE] Updated #{node}")
191
+ git_push(branch) if config.auto_push
192
+ end
193
+ def delete_node(node)
194
+ git_rm(node_path, "#{node}.json")
195
+ git_commit(node_path, "[NODE] Deleted #{node}")
196
+ git_push(branch) if config.auto_push
197
+ end
198
+
199
+ def save_role(role)
200
+ json = JSON.pretty_generate(Chef::Role.load(role))
201
+ role_file = File.expand_path( File.join(role_path, "#{role}.json") )
202
+ File.open(role_file, 'w'){ |f| f.puts(json) }
203
+ git_add(role_path, "#{role}.json")
204
+ git_commit(role_path, "[ROLE] Updated #{role}")
205
+ git_push(branch)
206
+ end
207
+ def delete_role(role)
208
+ git_rm(role_path, "#{role}.json")
209
+ if config.auto_push
210
+ git_commit(role_path, "[ROLE] Deleted #{role}")
211
+ git_push(branch)
212
+ end
213
+ end
214
+
215
+ def save_environment(environment)
216
+ json = JSON.pretty_generate(Chef::Environment.load(environment))
217
+ environment_file = File.expand_path( File.join(environment_path, "#{environment}.json") )
218
+ File.open(environment_file, 'w'){ |f| f.puts(json) }
219
+ git_add(environment_path, "#{environment}.json")
220
+ git_commit(environment_path, "[ENV] Updated #{environment}")
221
+ git_push(branch) if config.auto_push
222
+ end
223
+ def delete_environment(environment)
224
+ git_rm(environment_path, "#{environment}.json")
225
+ git_commit(environment_path, "[ENV] Deleted #{environment}")
226
+ git_push(branch) if config.auto_push
227
+ end
228
+
229
+ private
230
+ def git
231
+ safe_require 'git'
232
+ log = Logger.new(STDOUT)
233
+ log.level = Logger::WARN
234
+ @git ||= begin
235
+ cwd = FileUtils.pwd()
236
+ ::Git.open(get_parent_dir(cwd) , :log => log)
237
+ rescue Exception => e
238
+ ui.error "You are not currently in a git repository #{cwd}. Please ensure you are in a git repo, a repo subdirectory, or remove the git plugin from your KnifeSpork configuration!"
239
+ exit(0)
240
+ end
241
+ end
242
+
243
+ # In this case, a git pull will:
244
+ # - Stash local changes
245
+ # - Pull from the remote
246
+ # - Pop the stash
247
+ def git_pull(path)
248
+ if is_repo?(path)
249
+ ui.msg "Git: Pulling latest changes from #{path}"
250
+ output = IO.popen("cd #{path} && git pull 2>&1")
251
+ Process.wait
252
+ exit_code = $?
253
+ if !exit_code.exitstatus == 0
254
+ ui.error "#{output.read()}\n"
255
+ exit 1
256
+ end
257
+ end
258
+ end
259
+
260
+ def git_pull_submodules(path)
261
+ if is_repo?(path)
262
+ ui.msg "Pulling latest changes from git submodules (if any)"
263
+ top_level = `cd #{path} && git rev-parse --show-toplevel 2>&1`.chomp
264
+ if is_submodule?(top_level)
265
+ top_level = get_parent_dir(top_level)
266
+ end
267
+ output = IO.popen("cd #{top_level} && git submodule foreach git pull 2>&1")
268
+ Process.wait
269
+ exit_code = $?
270
+ if !exit_code.exitstatus == 0
271
+ ui.error "#{output.read()}\n"
272
+ exit 1
273
+ end
274
+ end
275
+ end
276
+
277
+ def git_add(filepath,filename)
278
+ if is_repo?(filepath)
279
+ ui.msg "Git add'ing #{filepath}/#{filename}"
280
+ output = IO.popen("cd #{filepath} && git add #{filename}")
281
+ Process.wait
282
+ exit_code = $?
283
+ if !exit_code.exitstatus == 0
284
+ ui.error "#{output.read()}\n"
285
+ exit 1
286
+ end
287
+ end
288
+ end
289
+
290
+ def git_commit(filepath, msg)
291
+ begin
292
+ if is_repo?(filepath)
293
+ ui.msg "Git: Committing changes..."
294
+ git.commit msg
295
+ end
296
+ rescue ::Git::GitExecuteError;
297
+ end
298
+ end
299
+
300
+ def git_push(branch)
301
+ begin
302
+ ui.msg "Git: Pushing to #{branch}"
303
+ git.push "origin", branch
304
+ rescue ::Git::GitExecuteError => e
305
+ ui.error "Could not push to master: #{e.message}"
306
+ end
307
+ end
308
+
309
+ def git_rm(filepath, filename)
310
+ if is_repo?(filepath)
311
+ ui.msg "Git rm'ing #{filepath}/#{filename}"
312
+ output = IO.popen("cd #{filepath} && git rm #{filename}")
313
+ Process.wait
314
+ exit_code = $?
315
+ if !exit_code.exitstatus == 0
316
+ ui.error "#{output.read()}\n"
317
+ exit 1
318
+ end
319
+ end
320
+ end
321
+
322
+ def git_tag(tag)
323
+ begin
324
+ git.add_tag(tag)
325
+ rescue ::Git::GitExecuteError => e
326
+ ui.error "Could not tag #{tag_name}. Does it already exist?"
327
+ ui.error 'You may need to delete the tag before running promote again.'
328
+ end
329
+ end
330
+
331
+ def is_repo?(path)
332
+ output = IO.popen("cd #{path} && git rev-parse --git-dir 2>&1")
333
+ Process.wait
334
+ if $? != 0
335
+ ui.warn "#{path} is not a git repo, skipping..."
336
+ return false
337
+ else
338
+ return true
339
+ end
340
+ end
341
+
342
+ def is_submodule?(path)
343
+ top_level = `cd #{path} && git rev-parse --show-toplevel 2>&1`.chomp
344
+ output = IO.popen("cd #{top_level}/.. && git rev-parse --show-toplevel 2>&1")
345
+ Process.wait
346
+ if $? != 0
347
+ return false
348
+ else
349
+ return true
350
+ end
351
+ end
352
+
353
+ def get_parent_dir(path)
354
+ top_level = path
355
+ return_code = 0
356
+ while return_code == 0
357
+ output = IO.popen("cd #{top_level}/.. && git rev-parse --show-toplevel 2>&1")
358
+ Process.wait
359
+ return_code = $?
360
+ cmd_output = output.read.chomp
361
+ #cygwin, I hate you for making me do this
362
+ if cmd_output.include?("fatal: Not a git repository")
363
+ return_code = 1
364
+ end
365
+ if return_code == 0
366
+ top_level = cmd_output
367
+ end
368
+ end
369
+ top_level
370
+ end
371
+
372
+ def remote
373
+ config.remote || 'origin'
374
+ end
375
+
376
+ def branch
377
+ config.branch || `git rev-parse --abbrev-ref HEAD`.chomp
378
+ end
379
+
380
+ def tag_name
381
+ cookbooks.collect{|c| "#{c.name}@#{c.version}"}.join('-')
382
+ end
383
+
384
+ def cookbook_path_for cookbook
385
+ if defined?(Berkshelf) and cookbook.is_a? Berkshelf::CachedCookbook
386
+ cookbook.path.to_s
387
+ else
388
+ cookbook.root_dir
389
+ end
390
+ end
391
+ end
392
+ end
393
+ end