knife-spork 0.1.11 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,122 +1,2 @@
1
- require 'rubygems'
2
- require 'rake'
3
- require 'date'
4
-
5
- #############################################################################
6
- #
7
- # Helper functions
8
- #
9
- #############################################################################
10
-
11
- def name
12
- @name ||= Dir['*.gemspec'].first.split('.').first
13
- end
14
-
15
- def version
16
- line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
17
- line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
18
- end
19
-
20
- def date
21
- Date.today.to_s
22
- end
23
-
24
- def rubyforge_project
25
- name
26
- end
27
-
28
- def gemspec_file
29
- "#{name}.gemspec"
30
- end
31
-
32
- def gem_file
33
- "#{name}-#{version}.gem"
34
- end
35
-
36
- def replace_header(head, header_name)
37
- head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
38
- end
39
-
40
- #############################################################################
41
- #
42
- # Standard tasks
43
- #
44
- #############################################################################
45
-
46
- task :default => :validate
47
-
48
- desc "Open an irb session preloaded with this library"
49
- task :console do
50
- sh "irb -rubygems -r ./lib/#{name}.rb"
51
- end
52
-
53
- #############################################################################
54
- #
55
- # Custom tasks (add your own tasks here)
56
- #
57
- #############################################################################
58
-
59
-
60
-
61
- #############################################################################
62
- #
63
- # Packaging tasks
64
- #
65
- #############################################################################
66
-
67
- desc "Create tag v#{version} and build and push #{gem_file} to Rubygems"
68
- task :release => :build do
69
- unless `git branch` =~ /^\* master$/
70
- puts "You must be on the master branch to release!"
71
- exit!
72
- end
73
- sh "git commit --allow-empty -a -m 'Release #{version}'"
74
- sh "git tag v#{version}"
75
- sh "git push origin master"
76
- sh "git push origin v#{version}"
77
- sh "gem push pkg/#{name}-#{version}.gem"
78
- end
79
-
80
- desc "Build #{gem_file} into the pkg directory"
81
- task :build => :gemspec do
82
- sh "mkdir -p pkg"
83
- sh "gem build #{gemspec_file}"
84
- sh "mv #{gem_file} pkg"
85
- end
86
-
87
- desc "Generate #{gemspec_file}"
88
- task :gemspec => :validate do
89
- # read spec file and split out manifest section
90
- spec = File.read(gemspec_file)
91
- head, manifest, tail = spec.split(" # = MANIFEST =\n")
92
-
93
- # replace name version and date
94
- replace_header(head, :name)
95
- replace_header(head, :version)
96
- replace_header(head, :date)
97
- #comment this out if your rubyforge_project has a different name
98
- replace_header(head, :rubyforge_project)
99
-
100
- # determine file list from git ls-files
101
- files = `git ls-files`.
102
- split("\n").
103
- sort.
104
- reject { |file| file =~ /^\./ }.
105
- reject { |file| file =~ /^(rdoc|pkg)/ }.
106
- map { |file| " #{file}" }.
107
- join("\n")
108
-
109
- # piece file back together and write
110
- manifest = " s.files = %w[\n#{files}\n ]\n"
111
- spec = [head, manifest, tail].join(" # = MANIFEST =\n")
112
- File.open(gemspec_file, 'w') { |io| io.write(spec) }
113
- puts "Updated #{gemspec_file}"
114
- end
115
-
116
- desc "Validate #{gemspec_file}"
117
- task :validate do
118
- unless Dir['VERSION*'].empty?
119
- puts "A `VERSION` file at root level violates Gem best practices."
120
- exit!
121
- end
122
- end
1
+ #!/usr/bin/env rake
2
+ require 'bundler/gem_tasks'
data/knife-spork.gemspec CHANGED
@@ -1,68 +1,21 @@
1
- ## This is the rakegem gemspec template. Make sure you read and understand
2
- ## all of the comments. Some sections require modification, and others can
3
- ## be deleted if you don't need them. Once you understand the contents of
4
- ## this file, feel free to delete any comments that begin with two hash marks.
5
- ## You can find comprehensive Gem::Specification documentation, at
6
- ## http://docs.rubygems.org/read/chapter/20
7
- Gem::Specification.new do |s|
8
- s.specification_version = 2 if s.respond_to? :specification_version=
9
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
10
- s.rubygems_version = '1.3.5'
11
-
12
- ## Leave these as is they will be modified for you by the rake gemspec task.
13
- ## If your rubyforge_project name is different, then edit it and comment out
14
- ## the sub! line in the Rakefile
15
- s.name = 'knife-spork'
16
- s.version = '0.1.11'
17
- s.date = '2012-06-05'
18
- s.rubyforge_project = 'knife-spork'
19
-
20
- ## Make sure your summary is short. The description may be as long
21
- ## as you like.
22
- s.summary = "A workflow plugin to help many devs work with the same chef repo/server"
23
- s.description = "A workflow plugin to help many devs work with the same chef repo/server"
24
-
25
- ## List the primary authors. If there are a bunch of authors, it's probably
26
- ## better to set the email to an email list or something. If you don't have
27
- ## a custom homepage, consider using your GitHub URL or the like.
28
- s.authors = ["Jon Cowie"]
29
- s.email = 'jonlives@gmail.com'
30
- s.homepage = 'https://github.com/jonlives/knife-spork'
31
-
32
- ## This gets added to the $LOAD_PATH so that 'lib/NAME.rb' can be required as
33
- ## require 'NAME.rb' or'/lib/NAME/file.rb' can be as require 'NAME/file.rb'
34
- s.require_paths = %w[lib]
35
-
36
- ## Specify any RDoc options here. You'll want to add your README and
37
- ## LICENSE files to the extra_rdoc_files list.
38
- s.rdoc_options = ["--charset=UTF-8"]
39
- s.extra_rdoc_files = %w[README.md]
40
-
41
- ## List your runtime dependencies here. Runtime dependencies are those
42
- ## that are needed for an end user to actually USE your code.
43
- s.add_dependency('chef', [">= 0.10.4"])
44
- s.add_dependency('git', [">= 1.2.5"])
45
- s.add_dependency('app_conf', [">= 0.4.0"])
46
- s.add_dependency('hipchat', [">= 0.4.0"])
47
-
48
- ## Leave this section as-is. It will be automatically generated from the
49
- ## contents of your Git repository via the gemspec task. DO NOT REMOVE
50
- ## THE MANIFEST COMMENTS, they are used as delimiters by the task.
51
- # = MANIFEST =
52
- s.files = %w[
53
- README.md
54
- CHANGELOG.md
55
- Rakefile
56
- knife-spork.gemspec
57
- lib/chef/knife/spork-bump.rb
58
- lib/chef/knife/spork-check.rb
59
- lib/chef/knife/spork-promote.rb
60
- lib/chef/knife/spork-upload.rb
61
- lib/knife-spork.rb
62
- ]
63
- # = MANIFEST =
64
-
65
- ## Test files will be grabbed from the file list. Make sure the path glob
66
- ## matches what you actually use.
67
- s.test_files = s.files.select { |path| path =~ /^test\/test_.*\.rb/ }
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.name = 'knife-spork'
5
+ gem.version = '1.0.0'
6
+ gem.authors = ["Jon Cowie"]
7
+ gem.email = 'jonlives@gmail.com'
8
+ gem.homepage = 'https://github.com/jonlives/knife-spork'
9
+ gem.summary = "A workflow plugin to help many devs work with the same chef repo/server"
10
+ gem.description = "A workflow plugin to help many devs work with the same chef repo/server"
11
+
12
+ gem.files = `git ls-files`.split($\)
13
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
14
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
+ gem.name = "knife-spork"
16
+ gem.require_paths = ["lib"]
17
+
18
+ gem.add_runtime_dependency 'chef', '>= 0.10.4'
19
+ gem.add_runtime_dependency 'git', '>= 1.2.5'
20
+ gem.add_runtime_dependency 'app_conf', '>= 0.4.0'
68
21
  end
@@ -1,228 +1,54 @@
1
- #
2
- # Modifying Author:: Jon Cowie (<jonlives@gmail.com>)
3
- # Copyright:: Copyright (c) 2011 Jon Cowie
4
- # License:: GPL
5
-
6
- # Based on the knife-cookbook-bump plugin by:
7
- # Alalanta (no license specified)
8
-
9
- require 'app_conf'
10
1
  require 'chef/knife'
11
- require 'chef/cookbook_loader'
12
- require 'chef/cookbook_uploader'
2
+ require 'knife-spork/runner'
13
3
 
14
4
  module KnifeSpork
15
5
  class SporkBump < Chef::Knife
6
+ include KnifeSpork::Runner
16
7
 
17
- TYPE_INDEX = { "major" => 0, "minor" => 1, "patch" => 2, "manual" => 3 }
8
+ TYPE_INDEX = { :major => 0, :minor => 1, :patch => 2, :manual => 3 }.freeze
18
9
 
19
- banner "knife spork bump COOKBOOK [MAJOR|MINOR|PATCH|MANUAL]"
20
-
21
- @@gitavail = true
22
- deps do
23
- begin
24
- require "git"
25
- rescue LoadError
26
- @@gitavail = false
27
- end
28
- end
10
+ banner 'knife spork bump COOKBOOK [major|minor|patch|manual]'
29
11
 
30
12
  def run
31
-
32
- if RUBY_VERSION.to_f < 1.9
33
- ui.fatal "Sorry, knife-spork requires ruby 1.9 or newer."
34
- exit 1
35
- end
36
-
37
13
  self.config = Chef::Config.merge!(config)
14
+ @cookbook = load_cookbook(name_args.first)
38
15
 
39
- @conf = AppConf.new
40
-
41
- if File.exists?("#{config[:cookbook_path].first.gsub("cookbooks","")}config/spork-config.yml")
42
- @conf.load("#{config[:cookbook_path].first.gsub("cookbooks","")}config/spork-config.yml")
43
- ui.msg "Loaded config file #{config[:cookbook_path].first.gsub("cookbooks","")}config/spork-config.yml...\n\n"
44
- end
45
-
46
- if File.exists?("/etc/spork-config.yml")
47
- @conf.load("/etc/spork-config.yml")
48
- ui.msg "Loaded config file /etc/spork-config.yml...\n\n"
49
- end
50
-
51
- if File.exists?(File.expand_path("~/.chef/spork-config.yml"))
52
- @conf.load(File.expand_path("~/.chef/spork-config.yml"))
53
- ui.msg "Loaded config file #{File.expand_path("~/.chef/spork-config.yml")}...\n\n"
54
- end
55
-
56
- bump_type=""
57
-
58
- if !config.has_key?(:cookbook_path)
59
- ui.fatal "No default cookbook_path; Specify with -o or fix your knife.rb."
60
- show_usage
61
- exit 1
62
- end
63
-
64
- if name_args.size == 0
65
- show_usage
66
- exit 0
67
- end
68
-
69
- if name_args.size == 3
70
- bump_type = name_args[1]
71
- elsif name_args.size == 2
72
- bump_type = name_args.last
73
- elsif name_args.size == 1
74
- bump_type = "patch"
75
- else
76
- ui.fatal "Please specify the cookbook whose version you which to bump, and the type of bump you wish to apply."
77
- show_usage
78
- exit 1
79
- end
80
-
81
- unless TYPE_INDEX.has_key?(bump_type)
82
- ui.fatal "Sorry, '#{name_args.last}' isn't a valid bump type. Specify one of 'major', 'minor', 'patch' or 'manual'"
83
- show_usage
84
- exit 1
85
- end
86
-
87
- cookbook = name_args.first
88
- cookbook_path = cookbook_repo[cookbook].root_dir.gsub("#{cookbook}","")
89
-
90
- if !@conf.git.nil? && @conf.git.enabled
91
- if !@@gitavail
92
- ui.msg "Git gem not available, skipping git pull.\n\n"
93
- else
94
- git_pull_if_repo([cookbook_path])
95
- end
96
- end
97
-
98
- if bump_type == "manual"
99
- manual_version = name_args.last
100
- patch_manual(cookbook_path, cookbook, manual_version)
101
- else
102
- patch(cookbook_path, cookbook, bump_type)
103
- end
104
-
105
- if !@conf.git.nil? && @conf.git.enabled
106
- if !@@gitavail
107
- ui.msg "Git gem not available, skipping git add.\n\n"
108
- else
109
- git_add(cookbook)
110
- end
111
- end
16
+ run_plugins(:before_bump)
17
+ bump
18
+ run_plugins(:after_bump)
112
19
  end
113
20
 
114
- def cookbook_repo
115
- @cookbook_loader ||= begin
116
- Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::FileSystemFileVendor.new(manifest, config[:cookbook_path]) }
117
- Chef::CookbookLoader.new(config[:cookbook_path])
118
- end
119
- end
120
-
121
- def patch(cookbook_path, cookbook, type)
122
- t = TYPE_INDEX[type]
123
- current_version = get_version(cookbook_path, cookbook).split(".").map{|i| i.to_i}
124
- bumped_version = current_version.clone
125
- bumped_version[t] = bumped_version[t] + 1
126
- while t < 2
127
- t+=1
128
- bumped_version[t] = 0
129
- end
130
- metadata_file = File.join(cookbook_path, cookbook, "metadata.rb")
131
- old_version = current_version.join('.')
132
- new_version = bumped_version.join('.')
133
- update_version(new_version, metadata_file)
134
- ui.msg("Bumping #{type} level of the #{cookbook} cookbook from #{old_version} to #{new_version}\n\n")
135
- end
136
-
137
- def patch_manual(cookbook_path, cookbook, version)
138
- current_version = get_version(cookbook_path, cookbook)
139
- v = version.split(".")
140
- if v.size < 3 or v.size > 3
141
- ui.msg "That isn't a valid version number to bump to."
142
- exit 1
143
- end
21
+ private
22
+ def bump
23
+ old_version = @cookbook.version
144
24
 
145
- v.each do |v_comp|
146
- if !v_comp.is_i?
147
- ui.msg "That isn't a valid version number to bump to."
148
- exit 1
149
- end
25
+ if bump_type == 3
26
+ # manual bump
27
+ version_array = manual_bump_version.split('.')
28
+ else
29
+ # major, minor, or patch bump
30
+ version_array = old_version.split('.').collect{ |i| i.to_i }
31
+ version_array[bump_type] += 1
32
+ ((bump_type+1)..2).each{ |i| version_array[i] = 0 } # reset all lower version numbers to 0
150
33
  end
151
34
 
152
- metadata_file = File.join(cookbook_path, cookbook, "metadata.rb")
153
- update_version(version, metadata_file)
154
- ui.msg("Manually bumped version of the #{cookbook} cookbook from #{current_version} to #{version}")
155
- end
35
+ new_version = version_array.join('.')
156
36
 
157
- def update_version(new_version, metadata_file)
158
- open_file = File.open(metadata_file, "r")
159
- body_of_file = open_file.read
160
- open_file.close
161
- body_of_file.gsub!(/version\s+"[0-9\.]+"/, "version \"#{new_version}\"")
162
- File.open(metadata_file, "w") { |file| file << body_of_file }
163
- end
37
+ metadata_file = "#{@cookbook.root_dir}/metadata.rb"
38
+ new_contents = File.read(metadata_file).gsub(/version\s+['"][0-9\.]+['"]/, "version \"#{new_version}\"")
39
+ File.open(metadata_file, 'w'){ |f| f.write(new_contents) }
164
40
 
165
- def get_version(cookbook_path, cookbook)
166
- loader = ::Chef::CookbookLoader.new(cookbook_path)
167
- return loader[cookbook].version
41
+ ui.info "Successfully bumped #{@cookbook.name} to v#{new_version}!"
168
42
  end
169
43
 
170
- def git_add(cookbook)
171
- strio = StringIO.new
172
- l = Logger.new strio
173
- cookbook_path = cookbook_repo[cookbook].root_dir.gsub("#{cookbook}","")
174
- begin
175
- path = cookbook_path.gsub("/site-cookbooks","").gsub("/cookbooks","")
176
- ui.msg "Opening git repo #{path}\n\n"
177
- g = Git.open(path, :log => Logger.new(strio))
178
- ui.msg "Git add'ing #{cookbook_path}#{cookbook}/metadata.rb\n\n"
179
- g.add("#{cookbook_path}/#{cookbook}/metadata.rb")
180
- rescue ArgumentError => e
181
- ui.warn "Git: The root of your chef repo doesn't look like it's a git repo. Skipping git add...\n\n"
182
- rescue
183
- ui.warn "Git: Cookbook bump succeeded, but something went wrong with git add metadata.rb, so you'll want to manually git add it. Dumping log info..."
184
- ui.warn "#{strio.string}"
185
- end
44
+ def bump_type
45
+ TYPE_INDEX[(name_args[1] || 'patch').to_sym]
186
46
  end
187
-
188
- def git_pull_if_repo(cookbook_path)
189
- strio = StringIO.new
190
- l = Logger.new strio
191
- begin
192
- path = cookbook_path[0].gsub("/site-cookbooks","").gsub("/cookbooks","")
193
- ui.msg "Opening git repo #{path}\n\n"
194
- g = Git.open(path, :log => Logger.new(strio))
195
- ui.msg "Pulling latest changes from git\n\n"
196
- output = IO.popen ("cd #{path} && git pull 2>&1")
197
- Process.wait
198
- exit_code = $?
199
- if exit_code.exitstatus == 0
200
- ui.msg "#{output.read()}\n"
201
- else
202
- ui.error "#{output.read()}\n"
203
- exit 1
204
- end
205
-
206
- ui.msg "Pulling latest changes from git submodules (if any)\n\n"
207
- output = IO.popen ("cd #{path} && git submodule foreach git pull 2>&1")
208
- Process.wait
209
- exit_code = $?
210
- if exit_code.exitstatus == 0
211
- ui.msg "#{output.read()}\n"
212
- else
213
- ui.error "#{output.read()}\n"
214
- exit 1
215
- end
216
- rescue ArgumentError => e
217
- ui.warn "Git: #{cookbook_path.join} doesn't look like it's a git repo. Skipping git pull...\n\n"
218
- end
219
- end
220
- end
221
-
222
- end
223
47
 
224
- class String
225
- def is_i?
226
- !!(self =~ /^[-+]?[0-9]+$/)
48
+ def manual_bump_version
49
+ version = name_args.last
50
+ validate_version!(version)
51
+ version
227
52
  end
53
+ end
228
54
  end