lib/hoe.rb in hoe-1.2.2 vs lib/hoe.rb in hoe-1.3.0
- old
+ new
@@ -6,10 +6,11 @@
require 'rake/gempackagetask'
require 'rake/rdoctask'
require 'rake/testtask'
require 'rbconfig'
require 'rubyforge'
+require 'yaml'
##
# hoe - a tool to help rake
#
# Hoe is a simple rake/rubygems helper for project Rakefiles. It
@@ -62,16 +63,43 @@
# YAML formatted config file with the following settings:
#
# exclude:: A regular expression of files to exclude from
# +check_manifest+.
# publish_on_announce:: Run +publish_docs+ when you run +release+.
+# signing_key_file:: Signs your gems with this private key.
+# signing_cert_file:: Signs your gem with this certificate.
# blogs:: An array of hashes of blog settings.
#
# Run +config_hoe+ and see ~/.hoerc for examples.
#
+# === Signing Gems:
+#
+# Run the 'generate_key' task. This will:
+#
+# 1. Configure your ~/.hoerc.
+# 2. Generate a signing key and certificate.
+# 3. Install the private key and public certificate files into ~/.gem.
+# 4. Upload the certificate to RubyForge.
+#
+# Hoe will now generate signed gems when the package task is run. If you have
+# multiple machines you build gems on, be sure to install your key and
+# certificate on each machine.
+#
+# Keep your private key secret! Keep your private key safe!
+#
+# To make sure your gems are signed run:
+#
+# rake package; tar tf pkg/yourproject-1.2.3.gem
+#
+# If your gem is signed you will see:
+#
+# data.tar.gz
+# data.tar.gz.sig
+# metadata.gz
+# metadata.gz.sig
class Hoe
- VERSION = '1.2.2'
+ VERSION = '1.3.0'
ruby_prefix = Config::CONFIG['prefix']
sitelibdir = Config::CONFIG['sitelibdir']
##
@@ -241,11 +269,11 @@
self.description = "The author was too lazy to write a description"
self.email = "ryand-ruby@zenspider.com"
self.extra_deps = []
self.need_tar = true
self.need_zip = false
- self.rdoc_pattern = /^(lib|bin)|txt$/
+ self.rdoc_pattern = /^(lib|bin|ext)|txt$/
self.remote_rdoc_dir = name
self.rsync_args = '-av --delete'
self.rubyforge_name = name.downcase
self.spec_extras = {}
self.summary = "The author was too lazy to write a summary"
@@ -257,13 +285,12 @@
hoe_deps = {
'rake' => ">= #{RAKEVERSION}",
'rubyforge' => ">= #{::RubyForge::VERSION}",
}
- self.extra_deps = Array(extra_deps) # just in case user used = instead of <<
- self.extra_deps = [extra_deps] unless
- extra_deps.empty? or Array === extra_deps.first
+ self.extra_deps = Array(extra_deps).map { |o| String === o ? [o] : o }
+
if name == 'hoe' then
hoe_deps.each do |pkg, version|
extra_deps << [pkg, version]
end
else
@@ -272,10 +299,17 @@
define_tasks
end
def define_tasks # :nodoc:
+ def with_config # :nodoc:
+ rc = File.expand_path("~/.hoerc")
+ exists = File.exist? rc
+ config = exists ? YAML.load_file(rc) : {}
+ yield(config, rc)
+ end
+
desc 'Run the default tasks'
task :default => :test
desc 'Run the test suite. Use FILTER to add to the command line.'
task :test do
@@ -299,10 +333,22 @@
end
############################################################
# Packaging and Installing
+ signing_key = nil
+ cert_chain = []
+
+ with_config do |config, path|
+ break unless config['signing_key_file'] and config['signing_cert_file']
+ key_file = File.expand_path config['signing_key_file'].to_s
+ signing_key = key_file if File.exist? key_file
+
+ cert_file = File.expand_path config['signing_cert_file'].to_s
+ cert_chain << cert_file if File.exist? cert_file
+ end
+
self.spec = Gem::Specification.new do |s|
s.name = name
s.version = version
s.summary = summary
case author
@@ -336,10 +382,15 @@
s.test_file = "test/test_all.rb"
else
s.test_files = Dir[*test_globs]
end
+ if signing_key and cert_chain then
+ s.signing_key = signing_key
+ s.cert_chain = cert_chain
+ end
+
# Do any extra stuff the user wants
spec_extras.each do |msg, val|
case val
when Proc
val.call(s.send(msg))
@@ -422,11 +473,11 @@
############################################################
# Doco
Rake::RDocTask.new(:docs) do |rd|
rd.main = "README.txt"
- rd.options << '-d' if RUBY_PLATFORM !~ /win32/ and `which dot` =~ /\/dot/
+ rd.options << '-d' if RUBY_PLATFORM !~ /win32/ and `which dot` =~ /\/dot/ and not ENV['NODOT']
rd.rdoc_dir = 'doc'
files = spec.files.grep(rdoc_pattern)
files -= ['Manifest.txt']
rd.rdoc_files.push(*files)
@@ -452,36 +503,18 @@
sh %{rsync #{rsync_args} #{local_dir}/ #{host}:#{remote_dir}}
end
# no doco for this one
task :publish_on_announce do
- with_config do |rc, path|
- if rc["publish_on_announce"] then
- Rake::Task['publish_docs'].invoke
- end
+ with_config do |config, _|
+ Rake::Task['publish_docs'].invoke if config["publish_on_announce"]
end
end
############################################################
# Misc/Maintenance:
- def with_config(create=false) # :nodoc:
- require 'yaml'
- rc = File.expand_path("~/.hoerc")
-
- unless create then
- if test ?f, rc then
- config = YAML.load_file(rc)
- yield(config, rc)
- end
- else
- unless test ?f, rc then
- yield(rc)
- end
- end
- end
-
desc 'Run ZenTest against the package'
task :audit do
libs = %w(lib test ext).join(File::PATH_SEPARATOR)
sh "zentest -I=#{libs} #{spec.files.grep(/^(lib|test)/).join(' ')}"
end
@@ -494,32 +527,32 @@
end
end
desc 'Create a fresh ~/.hoerc file'
task :config_hoe do
- with_config(:create) do |rc, path|
- blog = {
+ with_config do |config, path|
+ default_config = {
"exclude" => /tmp$|CVS|\.svn/,
"publish_on_announce" => false,
+ "signing_key_file" => "~/.gem/gem-private_key.pem",
+ "signing_cert_file" => "~/.gem/gem-public_cert.pem",
"blogs" => [ {
"user" => "user",
"url" => "url",
"extra_headers" => {
"mt_convert_breaks" => "markdown"
},
"blog_id" => "blog_id",
"password"=>"password",
} ],
}
- File.open(rc, "w") do |f|
- YAML.dump(blog, f)
+ File.open(path, "w") do |f|
+ YAML.dump(default_config.merge(config), f)
end
- end
- with_config do |rc, path|
editor = ENV['EDITOR'] || 'vi'
- system "#{editor} #{path}"
+ system "#{editor} #{path}" if ENV['SHOW_EDITOR'] != 'no'
end
end
desc 'Generate email announcement file.'
task :email do
@@ -543,12 +576,13 @@
desc 'Post announcement to blog.'
task :post_blog do
require 'xmlrpc/client'
with_config do |config, path|
- subject, title, body, urls = announcement
+ break unless config['blogs']
+ subject, title, body, urls = announcement
body += "\n\n#{urls}"
config['blogs'].each do |site|
server = XMLRPC::Client.new2(site['url'])
content = site['extra_headers'].merge(:title => title,
@@ -591,9 +625,59 @@
end
files = files.sort.join "\n"
File.open f, 'w' do |fp| fp.puts files end
system "#{DIFF} -du Manifest.txt #{f}"
rm f
+ end
+ end
+
+ desc 'Generate a key for signing your gems.'
+ task :generate_key do
+ email = spec.email
+ abort "No email in your gemspec" if email.nil? or email.empty?
+
+ key_file = with_config { |config, _| config['signing_key_file'] }
+ cert_file = with_config { |config, _| config['signing_cert_file'] }
+
+ if key_file.nil? or cert_file.nil? then
+ ENV['SHOW_EDITOR'] ||= 'no'
+ Rake::Task['config_hoe'].invoke
+
+ key_file = with_config { |config, _| config['signing_key_file'] }
+ cert_file = with_config { |config, _| config['signing_cert_file'] }
+ end
+
+ key_file = File.expand_path key_file
+ cert_file = File.expand_path cert_file
+
+ unless File.exist? key_file or File.exist? cert_file then
+ sh "gem cert --build #{email}"
+ mv "gem-private_key.pem", key_file, :verbose => true
+ mv "gem-public_cert.pem", cert_file, :verbose => true
+
+ puts "Installed key and certificate."
+
+ rf = RubyForge.new
+ rf.login
+
+ cert_package = "#{rubyforge_name}-certificates"
+
+ begin
+ rf.lookup 'package', cert_package
+ rescue
+ rf.create_package rubyforge_name, cert_package
+ end
+
+ begin
+ rf.lookup('release', cert_package)['certificates']
+ rf.add_file rubyforge_name, cert_package, 'certificates', cert_file
+ rescue
+ rf.add_release rubyforge_name, cert_package, 'certificates', cert_file
+ end
+
+ puts "Uploaded certificate to release \"certificates\" in package #{cert_package}"
+ else
+ puts "Keys already exist."
end
end
end # end define