pg-jdguyot 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
data/rake/packaging.rb ADDED
@@ -0,0 +1,129 @@
1
+ #####################################################################
2
+ ### P A C K A G I N G T A S K S
3
+ #####################################################################
4
+
5
+ require 'rbconfig'
6
+ require 'pathname'
7
+ require 'rubygems/package_task'
8
+
9
+
10
+ include Config
11
+
12
+ ### Task: prerelease
13
+ desc "Append the package build number to package versions"
14
+ task :prerelease do
15
+ GEMSPEC.version.version << "pre#{PKG_BUILD}"
16
+ Rake::Task[:gem].clear
17
+
18
+ Gem::PackageTask.new( GEMSPEC ) do |pkg|
19
+ pkg.need_zip = true
20
+ pkg.need_tar = true
21
+ end
22
+ end
23
+
24
+
25
+ ### Task: gem
26
+ ### Task: package
27
+ Rake::PackageTask.new( PKG_NAME, PKG_VERSION ) do |task|
28
+ task.need_tar_gz = true
29
+ task.need_tar_bz2 = true
30
+ task.need_zip = true
31
+ task.package_dir = PKGDIR.to_s
32
+ task.package_files = RELEASE_FILES.collect {|f| f.to_s }
33
+ end
34
+ task :package => [:gem]
35
+
36
+
37
+ Gem::PackageTask.new( GEMSPEC ) do |pkg|
38
+ pkg.need_zip = true
39
+ pkg.need_tar = true
40
+ end
41
+
42
+
43
+ ### Task: install
44
+ desc "Install #{PKG_NAME} as a conventional library"
45
+ task :install => "spec:quiet" do
46
+ log "Installing #{PKG_NAME} as a conventional library"
47
+ sitelib = Pathname.new( CONFIG['sitelibdir'] )
48
+ sitearch = Pathname.new( CONFIG['sitearchdir'] )
49
+ Dir.chdir( LIBDIR ) do
50
+ LIB_FILES.collect {|path| Pathname(path) }.each do |libfile|
51
+ relpath = libfile.relative_path_from( LIBDIR )
52
+ target = sitelib + relpath
53
+ FileUtils.mkpath target.dirname,
54
+ :mode => 0755, :verbose => true, :noop => $dryrun unless target.dirname.directory?
55
+ FileUtils.install relpath, target,
56
+ :mode => 0644, :verbose => true, :noop => $dryrun
57
+ end
58
+ end
59
+ if EXTDIR.exist?
60
+ trace " looking for a binary extension (%s)" % [ EXTDIR + "*.#{Config::CONFIG['DLEXT']}" ]
61
+ Dir.chdir( EXTDIR ) do
62
+ Pathname.glob( "*.#{Config::CONFIG['DLEXT']}" ) do |dl|
63
+ trace " found: #{dl}"
64
+ target = sitearch + dl.basename
65
+ FileUtils.install dl, target,
66
+ :mode => 0755, :verbose => true, :noop => $dryrun
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+
73
+
74
+ ### Task: install_gem
75
+ desc "Install #{PKG_NAME} from a locally-built gem"
76
+ task :install_gem => [:package] do
77
+ $stderr.puts
78
+ installer = Gem::Installer.new( %{pkg/#{PKG_FILE_NAME}.gem} )
79
+ installer.install
80
+ end
81
+
82
+
83
+ ### Task: uninstall
84
+ desc "Uninstall #{PKG_NAME} if it's been installed as a conventional library"
85
+ task :uninstall do
86
+ log "Uninstalling conventionally-installed #{PKG_NAME} library files"
87
+ sitelib = Pathname.new( CONFIG['sitelibdir'] )
88
+ sitearch = Pathname.new( CONFIG['sitearchdir'] )
89
+
90
+ Dir.chdir( LIBDIR ) do
91
+ LIB_FILES.collect {|path| Pathname(path) }.each do |libfile|
92
+ relpath = libfile.relative_path_from( LIBDIR )
93
+ target = sitelib + relpath
94
+ FileUtils.rm_f target, :verbose => true, :noop => $dryrun
95
+ FileUtils.rm_rf( target.dirname, :verbose => true, :noop => $dryrun ) if
96
+ target.dirname.entries.empty?
97
+ end
98
+ end
99
+ if EXTDIR.exist?
100
+ trace " looking for a binary extension (%s)" % [ EXTDIR + "*.#{Config::CONFIG['DLEXT']}" ]
101
+ Dir.chdir( EXTDIR ) do
102
+ Pathname.glob( "*.#{Config::CONFIG['DLEXT']}" ) do |dl|
103
+ trace " found: #{dl}"
104
+ target = sitearch + dl.basename
105
+ FileUtils.rm target, :verbose => true, :noop => $dryrun
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+
112
+ ### Task: uninstall_gem
113
+ desc "Install the #{PKG_NAME} gem"
114
+ task :uninstall_gem => [:clean] do
115
+ uninstaller = Gem::Uninstaller.new( PKG_FILE_NAME )
116
+ uninstaller.uninstall
117
+ end
118
+
119
+
120
+
121
+ desc "Add development depdendencies to the gemspec -- this is meant to be chained " +
122
+ "together with :gem"
123
+ task :include_dev_dependencies do
124
+ DEVELOPMENT_DEPENDENCIES.each do |name, version|
125
+ version = '>= 0' if version.length.zero?
126
+ GEMSPEC.add_development_dependency( name, version )
127
+ end
128
+ end
129
+
@@ -0,0 +1,341 @@
1
+ #####################################################################
2
+ ### P U B L I C A T I O N T A S K S
3
+ #####################################################################
4
+
5
+ RELEASE_NOTES_FILE = 'release.notes'
6
+ RELEASE_ANNOUNCE_FILE = 'release.ann'
7
+
8
+ GEM_PUBHOST = '' unless defined?( GEM_PUBHOST )
9
+
10
+ require 'net/smtp'
11
+ require 'net/protocol'
12
+ require 'openssl'
13
+
14
+ $publish_privately = false
15
+
16
+ ### Add SSL to Net::SMTP
17
+ class Net::SMTP
18
+
19
+ def ssl_start( helo='localhost.localdomain', user=nil, secret=nil, authtype=nil )
20
+ if block_given?
21
+ begin
22
+ do_ssl_start( helo, user, secret, authtype )
23
+ return yield( self )
24
+ ensure
25
+ do_finish
26
+ end
27
+ else
28
+ do_ssl_start( helo, user, secret, authtype )
29
+ return self
30
+ end
31
+ end
32
+
33
+
34
+ #######
35
+ private
36
+ #######
37
+
38
+ def do_ssl_start( helodomain, user, secret, authtype )
39
+ raise IOError, 'SMTP session already started' if @started
40
+ if user or secret
41
+ if self.method( :check_auth_args ).arity == 3
42
+ check_auth_args( user, secret, authtype )
43
+ else
44
+ check_auth_args( user, secret )
45
+ end
46
+ end
47
+
48
+ # Open the connection
49
+ @debug_output << "opening connection to #{@address}...\n" if @debug_output
50
+ sock = timeout( @open_timeout ) { TCPsocket.new(@address, @port) }
51
+
52
+ # Wrap it in the SSL layer
53
+ ssl_context = OpenSSL::SSL::SSLContext.new
54
+ ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
55
+ ssl_sock = OpenSSL::SSL::SSLSocket.new( sock, ssl_context )
56
+ ssl_sock.sync_close = true
57
+ ssl_sock.connect
58
+
59
+ # Wrap it in the message-oriented IO layer
60
+ sslmsgio = Net::InternetMessageIO.new( ssl_sock )
61
+ sslmsgio.read_timeout = @read_timeout
62
+ sslmsgio.debug_output = @debug_output
63
+
64
+ @socket = sslmsgio
65
+
66
+ check_response(critical { recv_response() })
67
+ begin
68
+ if @esmtp
69
+ ehlo helodomain
70
+ else
71
+ helo helodomain
72
+ end
73
+ rescue ProtocolError
74
+ if @esmtp
75
+ @esmtp = false
76
+ @error_occured = false
77
+ retry
78
+ end
79
+ raise
80
+ end
81
+ authenticate user, secret, authtype if user
82
+ @started = true
83
+ ensure
84
+ @socket.close if not @started and @socket and not @socket.closed?
85
+ end
86
+ end
87
+
88
+
89
+ begin
90
+ gem 'text-format'
91
+
92
+ require 'time'
93
+ require 'rake/tasklib'
94
+ require 'tmail'
95
+ require 'net/smtp'
96
+ require 'etc'
97
+ require 'socket'
98
+ require 'text/format'
99
+ require 'rubygems/gemcutter_utilities'
100
+
101
+ include Gem::GemcutterUtilities
102
+
103
+ ### Generate a valid RFC822 message-id
104
+ def gen_message_id
105
+ return "<%s.%s@%s>" % [
106
+ (Time.now.to_f * 10000).to_i.to_s( 36 ),
107
+ (rand( 2 ** 64 - 1 )).to_s( 36 ),
108
+ Socket.gethostname
109
+ ]
110
+ end
111
+
112
+
113
+ ### Fetch the rubygems API token if it hasn't been already.
114
+ def sign_in_to_rubygems
115
+ return if Gem.configuration.rubygems_api_key
116
+
117
+ log "Enter your RubyGems.org credentials."
118
+
119
+ email = prompt " Email: "
120
+ password = prompt_for_password( "Password: " )
121
+
122
+ response = rubygems_api_request( :get, "api/v1/api_key" ) do |request|
123
+ request.basic_auth( email, password )
124
+ end
125
+
126
+ with_response( response ) do |resp|
127
+ log "Signed in."
128
+ Gem.configuration.rubygems_api_key = resp.body
129
+ end
130
+ end
131
+
132
+
133
+ ### Push the gem at the specified +path+ to the rubygems server at +gemhost+.
134
+ def push_gem( path, gemhost )
135
+ ENV['RUBYGEMS_HOST'] = "http://#{gemhost}"
136
+
137
+ sign_in_to_rubygems()
138
+
139
+ response = rubygems_api_request( :post, "api/v1/gems" ) do |request|
140
+ request.body = Gem.read_binary( path )
141
+ request.add_field "Content-Length", request.body.size
142
+ request.add_field "Content-Type", "application/octet-stream"
143
+ request.add_field "Authorization", Gem.configuration.rubygems_api_key
144
+ end
145
+
146
+ case response
147
+ when Net::HTTPSuccess
148
+ log( response.body )
149
+ else
150
+ fail( response.body )
151
+ end
152
+ end
153
+
154
+
155
+ namespace :release do
156
+ task :default => [ :prep_release, :upload, :publish, :announce ]
157
+
158
+ desc "Re-publish the release with the current version number"
159
+ task :rerelease => [ :upload, :publish, :announce ]
160
+
161
+ desc "Re-run the publication tasks, but send notifications to debugging address"
162
+ task :test do
163
+ trace "Will publish privately"
164
+ $publish_privately = true
165
+ Rake::Task['release:rerelease'].invoke
166
+ end
167
+
168
+
169
+ desc "Generate the release notes"
170
+ task :notes => [RELEASE_NOTES_FILE]
171
+ file RELEASE_NOTES_FILE do |task|
172
+ last_tag = MercurialHelpers.get_tags.grep( /\d+\.\d+\.\d+/ ).
173
+ collect {|ver| vvec(ver) }.sort.last.unpack( 'N*' ).join('.')
174
+
175
+ File.open( task.name, File::WRONLY|File::TRUNC|File::CREAT ) do |fh|
176
+ fh.puts "Release Notes for #{PKG_VERSION}",
177
+ "--------------------------------", '', ''
178
+ end
179
+
180
+ edit task.name
181
+ end
182
+ CLOBBER.include( RELEASE_NOTES_FILE )
183
+
184
+ # Only define upload tasks if there's an upload host
185
+ if PROJECT_HOST.empty?
186
+ task :no_upload_host do
187
+ log "Skipping upload: no upload host."
188
+ end
189
+ task :upload => :no_upload_host
190
+ task :upload_docs => :no_upload_host
191
+ task :upload_packages => :no_upload_host
192
+ else
193
+ desc "Upload project documentation and packages to #{PROJECT_HOST}"
194
+ task :upload => [ :upload_docs, :upload_packages ]
195
+ task :project => :upload # the old name
196
+
197
+ desc "Publish the project docs to #{PROJECT_HOST}"
198
+ task :upload_docs => [ :apidocs ] do
199
+ when_writing( "Publishing docs to #{PROJECT_SCPDOCURL}" ) do
200
+ log "Uploading API documentation to %s:%s" % [ PROJECT_HOST, PROJECT_DOCDIR ]
201
+ run 'ssh', PROJECT_HOST, "rm -rf #{PROJECT_DOCDIR}"
202
+ run 'scp', '-qCr', API_DOCSDIR, PROJECT_SCPDOCURL
203
+ end
204
+ end
205
+
206
+ desc "Publish the project packages to #{PROJECT_HOST}"
207
+ task :upload_packages => [ :package ] do
208
+ when_writing( "Uploading packages") do
209
+ pkgs = Pathname.glob( PKGDIR + "#{PKG_FILE_NAME}.{gem,tar.gz,tar.bz2,zip}" )
210
+ log "Uploading %d packages to #{PROJECT_SCPPUBURL}" % [ pkgs.length ]
211
+ pkgs.each do |pkgfile|
212
+ run 'scp', '-qC', pkgfile, PROJECT_SCPPUBURL
213
+ end
214
+ end
215
+ end
216
+ end
217
+
218
+ # Only define the announcement tasks if there are addresses to announce to
219
+ if RELEASE_ANNOUNCE_ADDRESSES.empty?
220
+ task :no_announce_addresses do
221
+ log "Skipping announcement: no announce addresses"
222
+ end
223
+ task :announce => :no_announce_addresses
224
+
225
+ else
226
+ file RELEASE_ANNOUNCE_FILE => [RELEASE_NOTES_FILE] do |task|
227
+ relnotes = File.read( RELEASE_NOTES_FILE )
228
+ announce_body = %{
229
+
230
+ Version #{PKG_VERSION} of #{PKG_NAME} has been released.
231
+
232
+ #{Text::Format.new(:first_indent => 0).format_one_paragraph(GEMSPEC.description)}
233
+
234
+ == Project Page
235
+
236
+ #{GEMSPEC.homepage}
237
+
238
+ == Installation
239
+
240
+ $ sudo gem install #{GEMSPEC.name}
241
+
242
+ == Changes
243
+ #{relnotes}
244
+ }.gsub( /^\t+/, '' )
245
+
246
+ File.open( task.name, File::WRONLY|File::TRUNC|File::CREAT ) do |fh|
247
+ fh.print( announce_body )
248
+ end
249
+
250
+ edit task.name
251
+ end
252
+ CLOBBER.include( RELEASE_ANNOUNCE_FILE )
253
+
254
+
255
+ desc 'Send out a release announcement'
256
+ task :announce => [RELEASE_ANNOUNCE_FILE] do
257
+ email = TMail::Mail.new
258
+
259
+ if $publish_privately || RELEASE_ANNOUNCE_ADDRESSES.empty?
260
+ trace "Sending private announce mail"
261
+ email.to = 'rubymage@gmail.com'
262
+ else
263
+ trace "Sending public announce mail"
264
+ email.to = RELEASE_ANNOUNCE_ADDRESSES
265
+ email.bcc = 'rubymage@gmail.com'
266
+ end
267
+
268
+ from = prompt_with_default( "Send announcement as:",
269
+ 'Michael Granger <ged@FaerieMUD.org>' ) or fail
270
+
271
+ email.from = from
272
+ email.subject = "[ANN] #{PKG_NAME} #{PKG_VERSION}"
273
+ email.body = File.read( RELEASE_ANNOUNCE_FILE )
274
+ email.date = Time.new
275
+
276
+ email.message_id = gen_message_id()
277
+
278
+ log "About to send the following email:"
279
+ puts '---',
280
+ email.to_s,
281
+ '---'
282
+
283
+ ask_for_confirmation( "Will send via #{SMTP_HOST}." ) do
284
+ pwent = Etc.getpwuid( Process.euid )
285
+ curuser = pwent ? pwent.name : 'unknown'
286
+ username = prompt_with_default( "SMTP user", curuser )
287
+ password = prompt_for_password()
288
+
289
+ trace "Creating SMTP connection to #{SMTP_HOST}:#{SMTP_PORT}"
290
+ smtp = Net::SMTP.new( SMTP_HOST, SMTP_PORT )
291
+ smtp.set_debug_output( $stdout )
292
+ smtp.esmtp = true
293
+
294
+ trace "connecting..."
295
+ smtp.ssl_start( Socket.gethostname, username, password, :plain ) do |smtp|
296
+ trace "sending message..."
297
+ smtp.send_message( email.to_s, email.from, email.to )
298
+ end
299
+ trace "done."
300
+ end
301
+ end
302
+ end
303
+
304
+ if GEM_PUBHOST.empty?
305
+ task :no_gem_host do
306
+ log "Skipping gem push: no gem publication host."
307
+ end
308
+ task :publish => :no_gem_host
309
+ else
310
+ desc 'Publish the new gem to #{GEM_PUBHOST}'
311
+ task :publish => [:clean, :gem, :notes] do |task|
312
+ ask_for_confirmation( "Publish #{GEM_FILE_NAME} to #{GEM_PUBHOST}?", false ) do
313
+ gempath = PKGDIR + GEM_FILE_NAME
314
+ push_gem( gempath, GEM_PUBHOST )
315
+ end
316
+ end
317
+ end
318
+ end
319
+
320
+ rescue LoadError => err
321
+ if !Object.const_defined?( :Gem )
322
+ require 'rubygems'
323
+ retry
324
+ end
325
+
326
+ task :no_release_tasks do
327
+ fail "Release tasks not defined: #{err.message}"
328
+ end
329
+
330
+ task :release => :no_release_tasks
331
+ task "release:rerelease" => :no_release_tasks
332
+ task "release:announce" => :no_release_tasks
333
+ task "release:publish" => :no_release_tasks
334
+ task "release:notes" => :no_release_tasks
335
+ end
336
+
337
+ desc "Package up a release, publish it, and send out notifications"
338
+ task :release => 'release:default'
339
+ task :rerelease => 'release:rerelease'
340
+ task :testrelease => 'release:test'
341
+