gold 0.3.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.
data/History.txt ADDED
@@ -0,0 +1,16 @@
1
+ == 0.3.1 2009-10-02
2
+
3
+ * 1 major enhancement:
4
+ * Storing 'settings' in the projects .git directory
5
+ * Added 'rebase' method.
6
+ * Made a gem
7
+
8
+ == 0.2.0 2009-09-08
9
+
10
+ * 1 major enhancement:
11
+ * Added 'add_dev' and 'setup' methods
12
+
13
+ == 0.1.0 2009-09-06
14
+
15
+ * 1 major enhancement:
16
+ * Initial alpha release
data/README.txt ADDED
@@ -0,0 +1,67 @@
1
+ == SUMMARY:
2
+
3
+ Gold is a simple executable that helps git teamwork.
4
+
5
+ == DESCRIPTION:
6
+
7
+ This is the workflow we use when developing zena.
8
+
9
+ The main idea is that developers work on feature branches on their fork and send an
10
+ email to the reviewer when work is ready. The reviewer pulls from these branches,
11
+ checks that all is good and either apply the commits to the gold master or abort.
12
+
13
+ There is a script called 'gold' that helps use this workflow once the remote references
14
+ are added.
15
+
16
+ Any questions ? Ask zena's mailing list: http://zenadmin.org/en/community
17
+
18
+ ~~
19
+
20
+ == Workflow:
21
+
22
+ You need to update the Settings in the 'gold' script to match your own project and emails.
23
+
24
+ Developer setup
25
+ ---------------
26
+
27
+ 1. login on github (John)
28
+ 2. fork sandbox
29
+ 3. on local machine, clone your own fork
30
+ > git clone git@github.com:john/PROJECT.git
31
+ > cd PROJECT
32
+ > gold setup
33
+
34
+ Working on new 'floppy' feature
35
+ -------------------------------
36
+
37
+ [John] (developer, on his own fork)
38
+ > git checkout gold
39
+ > git pull
40
+ > git checkout -b floppy
41
+ > commit, commit
42
+ # propose
43
+ > gold propose
44
+
45
+ [reviewer]
46
+ # only if john is not a remote yet
47
+ > gold add_dev john
48
+ # review
49
+ > gold review john/floppy
50
+ # fail
51
+ > gold fail
52
+
53
+ [John]
54
+ > reset, commit, squash, etc
55
+ # propose again
56
+ > gold propose
57
+
58
+ [reviewer]
59
+ # review
60
+ > gold review john/floppy
61
+ # ok
62
+ > gold ok
63
+
64
+ [John]
65
+ # cleanup
66
+ > git co floppy
67
+ > gold cleanup
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'bones'
3
+ Bones.setup
4
+ rescue LoadError
5
+ begin
6
+ load 'tasks/setup.rb'
7
+ rescue LoadError
8
+ raise RuntimeError, '### please install the "bones" gem ###'
9
+ end
10
+ end
11
+
12
+ PROJ.name = 'gold'
13
+ PROJ.summary = 'Gold is a simple executable that helps git teamwork.'
14
+ PROJ.authors = 'Gaspard Bucher'
15
+ PROJ.email = 'gaspard@teti.ch'
16
+ PROJ.url = 'http://zenadmin.org/574'
17
+ PROJ.version = '0.3.1'
18
+ PROJ.rubyforge.name = 'gold'
19
+
20
+ PROJ.spec.opts << '--color'
21
+ PROJ.gem.files = ['History.txt', 'README.txt', 'bin/gold', 'Rakefile', 'lib/gold.rb']
data/bin/gold ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'gold'
4
+
5
+ Gold.run ARGV
data/lib/gold.rb ADDED
@@ -0,0 +1,282 @@
1
+ require 'fileutils'
2
+ require 'tempfile'
3
+ require 'yaml'
4
+
5
+ # Sending mail not working on mac os x ?
6
+ # http://www.macosxhints.com/article.php?story=20081217161612647
7
+
8
+ # install
9
+ # > sudo cp gold /usr/local/bin/
10
+ # > chmod a+x /usr/local/bin/gold
11
+
12
+ # TODO: move Settings inside each project ?
13
+
14
+ class Gold
15
+
16
+ DefaultSettings = {
17
+ 'gold_branch' => 'gold', # name of local branch tracking gold master (in developer's local git)
18
+ 'gold_remote' => 'zena', # name of remote 'gold' reference project
19
+ 'gold_repository' => 'git://github.com/zena/zena.git',
20
+ 'developer_name' => 'john', # developer's name (same as github account)
21
+ 'developer_email' => 'developer@example.com', # developer's email
22
+ 'reviewer' => 'reviewer@example.com' # reviewer's email
23
+ }
24
+
25
+ SettingsMessages = {
26
+ '1. gold_branch' => 'name of local branch that will track gold master',
27
+ '2. gold_remote' => 'name of remote gold master',
28
+ '3. gold_repository' => 'remote repository',
29
+ '4. developer_name' => 'developer\'s account on remote repository',
30
+ '5. developer_email' => 'developer\'s email',
31
+ '6. reviewer' => 'reviewer\'s email'
32
+ }
33
+
34
+ DefaultSettings.keys.each do |k|
35
+ define_method(k) do
36
+ settings[k]
37
+ end
38
+ end
39
+
40
+ def self.run(args)
41
+ self.new.run(args)
42
+ end
43
+
44
+ def run(args)
45
+ case args[0]
46
+ when 'add_dev'
47
+ add_dev args[1], args[2]
48
+ when 'check', 'review'
49
+ review args[1]
50
+ when 'propose'
51
+ propose args[1]
52
+ when 'settings'
53
+ create_settings_file
54
+ else
55
+ if args[0] && self.respond_to?(args[0])
56
+ send(args[0])
57
+ else
58
+ show_usage
59
+ end
60
+ end
61
+ end
62
+
63
+ def setup
64
+ return error("Could not create settings file #{settings_path.inspect}.") unless create_settings_file
65
+ return error("Could create remote #{gold_remote}.") unless system("git remote add #{gold_remote} #{gold_repository}")
66
+ return error("Could not fetch #{gold_remote}.") unless system("git fetch #{gold_remote}")
67
+ return error("Could not create #{gold_branch} branch.") unless system("git checkout --track -b #{gold_branch} #{gold_remote}/master")
68
+ end
69
+
70
+ def rebase
71
+ branch = current_branch
72
+ return error("Could not find current branch.") unless branch
73
+ return error("You cannot rebase the #{gold_branch} branch !") if branch == gold_branch
74
+ return error("You cannot rebase the master branch !") if branch == 'master'
75
+ return error("Could not checkout #{gold_branch}.") unless system("git checkout #{gold_branch}")
76
+ return error("Could not pull #{gold_branch}.") unless system("git pull")
77
+ return error("Could not checkout #{branch}.") unless system("git checkout #{branch}")
78
+ return error("Could not rebase --interactive #{gold_branch}.") unless system("git rebase --interactive #{gold_branch}")
79
+ end
80
+
81
+ def propose(msg)
82
+ branch = current_branch
83
+ return error("Could not find current branch.") unless branch
84
+ return error("You cannot propose the #{gold_branch} branch !") if branch == gold_branch
85
+ return error("You cannot propose the master branch !") if branch == 'master'
86
+ return error("Could not checkout #{gold_branch}.") unless system("git checkout #{gold_branch}")
87
+ return error("Could not pull #{gold_branch}.") unless system("git pull")
88
+ return error("Could not checkout #{branch}.") unless system("git checkout #{branch}")
89
+ return error("Could not rebase #{branch} with #{gold_branch}.") unless system("git rebase #{gold_branch}")
90
+ return error("Could not push #{branch} to origin.") unless system("git push origin +#{branch}")
91
+ subject = "#{gold_remote}: review #{developer_name}/#{branch}"
92
+ tmpf = Tempfile.new('gold_msg')
93
+ tmpf.write %Q{From:#{developer_email}
94
+ Subject:#{subject}
95
+
96
+ ============
97
+ gold review #{developer_name}/#{branch}
98
+ ============
99
+
100
+ #{msg}
101
+ }
102
+ tmpf.close
103
+ return error("Could not send email to #{reviewer}.") unless system("sendmail -F '#{developer_name}' #{reviewer} < #{tmpf.path}")
104
+ tmpf.delete
105
+ puts "Mail sent to #{reviewer}"
106
+ end
107
+
108
+ def add_dev(name, repo = nil)
109
+ return error("Missing 'developer name' parameter.") unless name
110
+ repo ||= "#{gold_repository.split('/')[0..2].join('/')}/#{name}/#{gold_remote}.git"
111
+ return error("Could add developer #{name} (#{repo}).") unless system("git remote add #{name} #{repo}")
112
+ return error("Could not fetch #{name}.") unless system("git fetch #{name}")
113
+ end
114
+
115
+ def review(remote_branch)
116
+ return error("Missing 'remote_branch' parameter.") unless remote_branch
117
+ return error("'remote_branch' format should be remote/branch.") unless remote_branch =~ /^(.+)\/(.+)$/
118
+ remote, branch = $1, $2
119
+ return error("Could not checkout master.") unless system("git co master")
120
+ return error("Could not checkout #{remote}_#{branch}.") unless system("git co -b #{remote}_#{branch}")
121
+ return error("Could not pull #{remote_branch}.") unless system("git pull #{remote} #{branch}")
122
+ return error("Could not rebase.") unless system("git rebase master")
123
+ system("git diff master | $EDITOR")
124
+ true
125
+ end
126
+
127
+ def ok
128
+ branch = current_branch
129
+ return error("Could not find current branch.") unless branch
130
+ return error("Could not rebase.") unless system("git rebase master")
131
+ return error("Could not checkout master.") unless system("git co master")
132
+ return error("Could not fast-forward merge #{branch} into master.") unless system("git merge --ff #{branch}")
133
+ return error("Could not delete #{branch}.") unless system("git branch -d #{branch}")
134
+ puts "-------------------\n\nSuccessfully applied #{branch} to golden master !\n\nPlease git push when you are ready."
135
+ end
136
+
137
+ def fail
138
+ branch = current_branch
139
+ return error("Could not find current branch.") unless branch
140
+ return error("You cannot 'fail' master !") unless branch != 'master'
141
+ return error("Could not checkout master.") unless system("git co master")
142
+ return nil unless remove(branch, true)
143
+ end
144
+
145
+ def cleanup
146
+ branch = current_branch
147
+ return error("Could not find current branch.") unless branch
148
+ return error("You cannot 'cleanup' master or #{gold_branch} !") if branch == 'master' || branch == gold_branch
149
+ return error("Could not checkout #{gold_branch}.") unless system("git co #{gold_branch}")
150
+ return error("Could not pull #{gold_remote}.") unless system("git pull #{gold_remote}")
151
+ return error("Could not checkout #{branch}.") unless system("git co #{branch}")
152
+ return error("Could rebase on top of #{gold_branch}.") unless system("git rebase #{gold_branch}")
153
+ return error("Could not checkout #{gold_branch}.") unless system("git co #{gold_branch}")
154
+ return nil unless remove(branch)
155
+ return error("Could not clear remote branch.") unless system("git push origin :#{branch}")
156
+ end
157
+
158
+
159
+ private
160
+
161
+ def error(msg)
162
+ puts msg
163
+ nil
164
+ end
165
+
166
+ def current_branch
167
+ branch = nil
168
+ `git branch`.split("\n").each do |b|
169
+ if b =~ /^\*\s+(.+)$/
170
+ branch = $1
171
+ break
172
+ end
173
+ end
174
+ branch
175
+ end
176
+
177
+ def remove(branch, force=false)
178
+ print "Remove branch #{branch} ? (y,N) "
179
+ yn = STDIN.gets
180
+ if yn.downcase.strip == 'y'
181
+ return error("Could not delete #{branch}.") unless system("git branch -#{force ? 'D' : 'd'} #{branch}")
182
+ true
183
+ else
184
+ return error("Could not checkout #{branch}.") unless system("git co #{branch}")
185
+ false
186
+ end
187
+ end
188
+
189
+ def create_settings_file
190
+ FileUtils::mkpath(File.dirname(settings_path)) unless File.exist?(File.dirname(settings_path))
191
+ defaults = settings
192
+ new_settings = {}
193
+ SettingsMessages.keys.sort.each do |key|
194
+ real_key = key.gsub(/\A.*? /,'')
195
+ print "#{SettingsMessages[key]} (#{defaults[real_key]}): "
196
+ value = STDIN.gets.chomp
197
+ new_settings[real_key] = value == '' ? DefaultSettings[real_key] : value
198
+ end
199
+ File.open(settings_path, 'wb') do |f|
200
+ f.puts YAML::dump(new_settings)
201
+ end
202
+ puts "New settings written to '#{settings_path}'"
203
+ true
204
+ end
205
+
206
+ def settings
207
+ @settings ||= begin
208
+ if File.exist?(settings_path)
209
+ YAML::load(File.read(settings_path))
210
+ else
211
+ DefaultSettings
212
+ end
213
+ end
214
+ end
215
+
216
+ def settings_path
217
+ @settings_path ||= begin
218
+ path = File.expand_path('.').split('/')
219
+ while path != []
220
+ if File.exist?(File.join(path + ['.git']))
221
+ break
222
+ else
223
+ path.pop
224
+ end
225
+ end
226
+ (path + ['.git', 'gold.yml']).flatten.join('/')
227
+ end
228
+ end
229
+
230
+ def show_usage
231
+ error(%Q{
232
+ Usage:
233
+
234
+ Reviewer
235
+ ========
236
+
237
+ Add a new developer reference
238
+ -----------------------------
239
+ > gold add_dev john
240
+ or
241
+ > gold add_dev john git://github.com/john/foo.git
242
+
243
+ Checkout a remote branch and view diff
244
+ --------------------------------------
245
+ > gold check john/floppy
246
+
247
+ Include commits into master branch
248
+ ----------------------------------
249
+ (on the new feature branch created by previous 'review')
250
+ > gold ok
251
+
252
+ The code is not ready yet, cleanup
253
+ ----------------------------------
254
+ (on the new feature branch created by previous 'review')
255
+ > gold fail
256
+
257
+ Developer
258
+ =========
259
+
260
+ Setup
261
+ -----
262
+ > gold setup
263
+ > gold settings
264
+
265
+ Rebase on top of latest gold
266
+ ----------------------------
267
+ (on the new feature branch)
268
+ > gold rebase
269
+
270
+ Propose branch
271
+ --------------
272
+ (on the new feature branch)
273
+ > gold propose
274
+
275
+ Cleanup after commit acceptation
276
+ --------------------------------
277
+ (on the new feature branch)
278
+ > gold cleanup
279
+
280
+ })
281
+ end
282
+ end
data/tasks/ann.rake ADDED
@@ -0,0 +1,80 @@
1
+
2
+ begin
3
+ require 'bones/smtp_tls'
4
+ rescue LoadError
5
+ require 'net/smtp'
6
+ end
7
+ require 'time'
8
+
9
+ namespace :ann do
10
+
11
+ # A prerequisites task that all other tasks depend upon
12
+ task :prereqs
13
+
14
+ file PROJ.ann.file do
15
+ ann = PROJ.ann
16
+ puts "Generating #{ann.file}"
17
+ File.open(ann.file,'w') do |fd|
18
+ fd.puts("#{PROJ.name} version #{PROJ.version}")
19
+ fd.puts(" by #{Array(PROJ.authors).first}") if PROJ.authors
20
+ fd.puts(" #{PROJ.url}") if PROJ.url.valid?
21
+ fd.puts(" (the \"#{PROJ.release_name}\" release)") if PROJ.release_name
22
+ fd.puts
23
+ fd.puts("== DESCRIPTION")
24
+ fd.puts
25
+ fd.puts(PROJ.description)
26
+ fd.puts
27
+ fd.puts(PROJ.changes.sub(%r/^.*$/, '== CHANGES'))
28
+ fd.puts
29
+ ann.paragraphs.each do |p|
30
+ fd.puts "== #{p.upcase}"
31
+ fd.puts
32
+ fd.puts paragraphs_of(PROJ.readme_file, p).join("\n\n")
33
+ fd.puts
34
+ end
35
+ fd.puts ann.text if ann.text
36
+ end
37
+ end
38
+
39
+ desc "Create an announcement file"
40
+ task :announcement => ['ann:prereqs', PROJ.ann.file]
41
+
42
+ desc "Send an email announcement"
43
+ task :email => ['ann:prereqs', PROJ.ann.file] do
44
+ ann = PROJ.ann
45
+ from = ann.email[:from] || Array(PROJ.authors).first || PROJ.email
46
+ to = Array(ann.email[:to])
47
+
48
+ ### build a mail header for RFC 822
49
+ rfc822msg = "From: #{from}\n"
50
+ rfc822msg << "To: #{to.join(',')}\n"
51
+ rfc822msg << "Subject: [ANN] #{PROJ.name} #{PROJ.version}"
52
+ rfc822msg << " (#{PROJ.release_name})" if PROJ.release_name
53
+ rfc822msg << "\n"
54
+ rfc822msg << "Date: #{Time.new.rfc822}\n"
55
+ rfc822msg << "Message-Id: "
56
+ rfc822msg << "<#{"%.8f" % Time.now.to_f}@#{ann.email[:domain]}>\n\n"
57
+ rfc822msg << File.read(ann.file)
58
+
59
+ params = [:server, :port, :domain, :acct, :passwd, :authtype].map do |key|
60
+ ann.email[key]
61
+ end
62
+
63
+ params[3] = PROJ.email if params[3].nil?
64
+
65
+ if params[4].nil?
66
+ STDOUT.write "Please enter your e-mail password (#{params[3]}): "
67
+ params[4] = STDIN.gets.chomp
68
+ end
69
+
70
+ ### send email
71
+ Net::SMTP.start(*params) {|smtp| smtp.sendmail(rfc822msg, from, to)}
72
+ end
73
+ end # namespace :ann
74
+
75
+ desc 'Alias to ann:announcement'
76
+ task :ann => 'ann:announcement'
77
+
78
+ CLOBBER << PROJ.ann.file
79
+
80
+ # EOF
data/tasks/bones.rake ADDED
@@ -0,0 +1,20 @@
1
+
2
+ if HAVE_BONES
3
+
4
+ namespace :bones do
5
+
6
+ desc 'Show the PROJ open struct'
7
+ task :debug do |t|
8
+ atr = if t.application.top_level_tasks.length == 2
9
+ t.application.top_level_tasks.pop
10
+ end
11
+
12
+ if atr then Bones::Debug.show_attr(PROJ, atr)
13
+ else Bones::Debug.show PROJ end
14
+ end
15
+
16
+ end # namespace :bones
17
+
18
+ end # HAVE_BONES
19
+
20
+ # EOF
data/tasks/gem.rake ADDED
@@ -0,0 +1,201 @@
1
+
2
+ require 'find'
3
+ require 'rake/packagetask'
4
+ require 'rubygems/user_interaction'
5
+ require 'rubygems/builder'
6
+
7
+ module Bones
8
+ class GemPackageTask < Rake::PackageTask
9
+ # Ruby GEM spec containing the metadata for this package. The
10
+ # name, version and package_files are automatically determined
11
+ # from the GEM spec and don't need to be explicitly provided.
12
+ #
13
+ attr_accessor :gem_spec
14
+
15
+ # Tasks from the Bones gem directory
16
+ attr_reader :bones_files
17
+
18
+ # Create a GEM Package task library. Automatically define the gem
19
+ # if a block is given. If no block is supplied, then +define+
20
+ # needs to be called to define the task.
21
+ #
22
+ def initialize(gem_spec)
23
+ init(gem_spec)
24
+ yield self if block_given?
25
+ define if block_given?
26
+ end
27
+
28
+ # Initialization tasks without the "yield self" or define
29
+ # operations.
30
+ #
31
+ def init(gem)
32
+ super(gem.name, gem.version)
33
+ @gem_spec = gem
34
+ @package_files += gem_spec.files if gem_spec.files
35
+ @bones_files = []
36
+
37
+ local_setup = File.join(Dir.pwd, %w[tasks setup.rb])
38
+ if !test(?e, local_setup)
39
+ Dir.glob(::Bones.path(%w[lib bones tasks *])).each {|fn| bones_files << fn}
40
+ end
41
+ end
42
+
43
+ # Create the Rake tasks and actions specified by this
44
+ # GemPackageTask. (+define+ is automatically called if a block is
45
+ # given to +new+).
46
+ #
47
+ def define
48
+ super
49
+ task :prereqs
50
+ task :package => ['gem:prereqs', "#{package_dir_path}/#{gem_file}"]
51
+ file "#{package_dir_path}/#{gem_file}" => [package_dir_path] + package_files + bones_files do
52
+ when_writing("Creating GEM") {
53
+ chdir(package_dir_path) do
54
+ Gem::Builder.new(gem_spec).build
55
+ verbose(true) {
56
+ mv gem_file, "../#{gem_file}"
57
+ }
58
+ end
59
+ }
60
+ end
61
+
62
+ file package_dir_path => bones_files do
63
+ mkdir_p package_dir rescue nil
64
+
65
+ gem_spec.files = (gem_spec.files +
66
+ bones_files.map {|fn| File.join('tasks', File.basename(fn))}).sort
67
+
68
+ bones_files.each do |fn|
69
+ base_fn = File.join('tasks', File.basename(fn))
70
+ f = File.join(package_dir_path, base_fn)
71
+ fdir = File.dirname(f)
72
+ mkdir_p(fdir) if !File.exist?(fdir)
73
+ if File.directory?(fn)
74
+ mkdir_p(f)
75
+ else
76
+ raise "file name conflict for '#{base_fn}' (conflicts with '#{fn}')" if test(?e, f)
77
+ safe_ln(fn, f)
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ def gem_file
84
+ if @gem_spec.platform == Gem::Platform::RUBY
85
+ "#{package_name}.gem"
86
+ else
87
+ "#{package_name}-#{@gem_spec.platform}.gem"
88
+ end
89
+ end
90
+ end # class GemPackageTask
91
+ end # module Bones
92
+
93
+ namespace :gem do
94
+
95
+ PROJ.gem._spec = Gem::Specification.new do |s|
96
+ s.name = PROJ.name
97
+ s.version = PROJ.version
98
+ s.summary = PROJ.summary
99
+ s.authors = Array(PROJ.authors)
100
+ s.email = PROJ.email
101
+ s.homepage = Array(PROJ.url).first
102
+ s.rubyforge_project = PROJ.rubyforge.name
103
+
104
+ s.description = PROJ.description
105
+
106
+ PROJ.gem.dependencies.each do |dep|
107
+ s.add_dependency(*dep)
108
+ end
109
+
110
+ PROJ.gem.development_dependencies.each do |dep|
111
+ s.add_development_dependency(*dep)
112
+ end
113
+
114
+ s.files = PROJ.gem.files
115
+ s.executables = PROJ.gem.executables.map {|fn| File.basename(fn)}
116
+ s.extensions = PROJ.gem.files.grep %r/extconf\.rb$/
117
+
118
+ s.bindir = 'bin'
119
+ dirs = Dir["{#{PROJ.libs.join(',')}}"]
120
+ s.require_paths = dirs unless dirs.empty?
121
+
122
+ incl = Regexp.new(PROJ.rdoc.include.join('|'))
123
+ excl = PROJ.rdoc.exclude.dup.concat %w[\.rb$ ^(\.\/|\/)?ext]
124
+ excl = Regexp.new(excl.join('|'))
125
+ rdoc_files = PROJ.gem.files.find_all do |fn|
126
+ case fn
127
+ when excl; false
128
+ when incl; true
129
+ else false end
130
+ end
131
+ s.rdoc_options = PROJ.rdoc.opts + ['--main', PROJ.rdoc.main]
132
+ s.extra_rdoc_files = rdoc_files
133
+ s.has_rdoc = true
134
+
135
+ if test ?f, PROJ.test.file
136
+ s.test_file = PROJ.test.file
137
+ else
138
+ s.test_files = PROJ.test.files.to_a
139
+ end
140
+
141
+ # Do any extra stuff the user wants
142
+ PROJ.gem.extras.each do |msg, val|
143
+ case val
144
+ when Proc
145
+ val.call(s.send(msg))
146
+ else
147
+ s.send "#{msg}=", val
148
+ end
149
+ end
150
+ end # Gem::Specification.new
151
+
152
+ Bones::GemPackageTask.new(PROJ.gem._spec) do |pkg|
153
+ pkg.need_tar = PROJ.gem.need_tar
154
+ pkg.need_zip = PROJ.gem.need_zip
155
+ end
156
+
157
+ desc 'Show information about the gem'
158
+ task :debug => 'gem:prereqs' do
159
+ puts PROJ.gem._spec.to_ruby
160
+ end
161
+
162
+ desc 'Write the gemspec '
163
+ task :spec => 'gem:prereqs' do
164
+ File.open("#{PROJ.name}.gemspec", 'w') do |f|
165
+ f.write PROJ.gem._spec.to_ruby
166
+ end
167
+ end
168
+
169
+ desc 'Install the gem'
170
+ task :install => [:clobber, 'gem:package'] do
171
+ sh "#{SUDO} #{GEM} install --local pkg/#{PROJ.gem._spec.full_name}"
172
+
173
+ # use this version of the command for rubygems > 1.0.0
174
+ #sh "#{SUDO} #{GEM} install --no-update-sources pkg/#{PROJ.gem._spec.full_name}"
175
+ end
176
+
177
+ desc 'Uninstall the gem'
178
+ task :uninstall do
179
+ installed_list = Gem.source_index.find_name(PROJ.name)
180
+ if installed_list and installed_list.collect { |s| s.version.to_s}.include?(PROJ.version) then
181
+ sh "#{SUDO} #{GEM} uninstall --version '#{PROJ.version}' --ignore-dependencies --executables #{PROJ.name}"
182
+ end
183
+ end
184
+
185
+ desc 'Reinstall the gem'
186
+ task :reinstall => [:uninstall, :install]
187
+
188
+ desc 'Cleanup the gem'
189
+ task :cleanup do
190
+ sh "#{SUDO} #{GEM} cleanup #{PROJ.gem._spec.name}"
191
+ end
192
+ end # namespace :gem
193
+
194
+
195
+ desc 'Alias to gem:package'
196
+ task :gem => 'gem:package'
197
+
198
+ task :clobber => 'gem:clobber_package'
199
+ remove_desc_for_task 'gem:clobber_package'
200
+
201
+ # EOF