lib/hoe.rb in hoe-1.7.0 vs lib/hoe.rb in hoe-1.8.0
- old
+ new
@@ -36,31 +36,35 @@
#
# # add other tasks here
#
# === Tasks Provided:
#
-# announce:: Create news email file and post to rubyforge.
-# audit:: Run ZenTest against the package.
-# check_manifest:: Verify the manifest.
-# clean:: Clean up all the extras.
-# config_hoe:: Create a fresh ~/.hoerc file.
-# debug_gem:: Show information about the gem.
-# default:: Run the default tasks.
-# docs:: Build the docs HTML Files
-# email:: Generate email announcement file.
-# gem:: Build the gem file hoe-1.5.0.gem
-# generate_key:: Generate a key for signing your gems.
-# install_gem:: Install the package as a gem.
-# multi:: Run the test suite using multiruby.
-# package:: Build all the packages
-# post_blog:: Post announcement to blog.
-# post_news:: Post announcement to rubyforge.
-# publish_docs:: Publish RDoc to RubyForge.
-# release:: Package and upload the release to rubyforge.
-# ridocs:: Generate ri locally for testing.
-# test:: Run the test suite.
-# test_deps:: Show which test files fail when run alone.
+# announce:: Create news email file and post to rubyforge.
+# audit:: Run ZenTest against the package.
+# check_manifest:: Verify the manifest.
+# clean:: Clean up all the extras.
+# config_hoe:: Create a fresh ~/.hoerc file.
+# debug_gem:: Show information about the gem.
+# default:: Run the default tasks.
+# deps:email:: Print a contact list for gems dependent on this gem
+# deps:fetch:: Fetch all the dependent gems of this gem into tarballs
+# deps:list:: List all the dependent gems of this gem
+# docs:: Build the docs HTML Files
+# email:: Generate email announcement file.
+# gem:: Build the gem file hoe-1.8.0.gem
+# generate_key:: Generate a key for signing your gems.
+# install_gem:: Install the package as a gem.
+# multi:: Run the test suite using multiruby.
+# package:: Build all the packages
+# post_blog:: Post announcement to blog.
+# post_news:: Post announcement to rubyforge.
+# publish_docs:: Publish RDoc to RubyForge.
+# release:: Package and upload the release to rubyforge.
+# ridocs:: Generate ri locally for testing.
+# tasks:: Generate a list of tasks for doco.
+# test:: Run the test suite.
+# test_deps:: Show which test files fail when run alone.
#
# === Extra Configuration Options:
#
# Run +config_hoe+ to generate a new ~/.hoerc file. The file is a
# YAML formatted config file with the following settings:
@@ -118,11 +122,12 @@
# This will set the +Gem::Specification+ platform to the one indicated in
# +FORCE_PLATFORM+ (instead of default Gem::Platform::CURRENT)
#
class Hoe
- VERSION = '1.7.0'
+ VERSION = '1.8.0'
+ GEMURL = URI.parse 'http://gems.rubyforge.org' # for namespace :deps below
ruby_prefix = Config::CONFIG['prefix']
sitelibdir = Config::CONFIG['sitelibdir']
##
@@ -302,19 +307,33 @@
# Optional: An array of test file patterns [default: test/**/test_*.rb]
attr_accessor :test_globs
##
+ # Optional: What test library to require [default: test/unit]
+
+ attr_accessor :testlib
+
+ ##
# Optional: The url(s) of the project. (can be array). Auto-populates.
attr_accessor :url
##
# *MANDATORY*: The version. Don't hardcode! use a constant in the project.
attr_accessor :version
+ ##
+ # Add extra dirs to both $: and RUBY_FLAGS (for test runs)
+
+ def self.add_include_dirs(*dirs)
+ dirs = dirs.flatten
+ $:.unshift(*dirs)
+ Hoe::RUBY_FLAGS.sub!(/-I/, "-I#{dirs.join(":")}:")
+ end
+
def normalize_deps deps
Array(deps).map { |o| String === o ? [o] : o }
end
def missing name
@@ -326,11 +345,11 @@
self.name = name
self.version = version
# Defaults
self.author = []
- self.clean_globs = %w(diff diff.txt email.txt ri
+ self.clean_globs = %w(diff diff.txt email.txt ri deps .source_index
*.gem *~ **/*~ *.rbc **/*.rbc)
self.description_sections = %w(description)
self.blog_categories = [name]
self.email = []
self.extra_deps = []
@@ -343,10 +362,11 @@
self.rsync_args = '-av --delete'
self.rubyforge_name = name.downcase
self.spec_extras = {}
self.summary_sentences = 1
self.test_globs = ['test/**/test_*.rb']
+ self.testlib = 'test/unit'
self.post_install_message = nil
yield self if block_given?
# Intuit values:
@@ -634,10 +654,137 @@
Rake::Task['publish_docs'].invoke if config["publish_on_announce"]
end
end
############################################################
+ # Dependencies:
+
+ namespace :deps do
+ require 'zlib' # HACK for rubygems 1.3.0
+ require 'rubygems/remote_fetcher'
+
+ @@index = nil
+
+ def self.get_source_index
+ return @@index if @@index
+
+ dump = unless File.exist? '.source_index' then
+ url = GEMURL + "Marshal.#{Gem.marshal_version}.Z"
+ dump = Gem::RemoteFetcher.fetcher.fetch_path url
+ dump = Gem.inflate dump
+ open '.source_index', 'wb' do |io| io.write dump end
+ dump
+ else
+ open '.source_index', 'rb' do |io| io.read end
+ end
+
+ @@index = Marshal.load dump
+ end
+
+ def self.get_latest_gems
+ @@cache ||= get_source_index.latest_specs
+ end
+
+ def self.get_gems_by_name
+ @@by_name ||= Hash[*get_latest_gems.map { |gem|
+ [gem.name, gem, gem.full_name, gem]
+ }.flatten]
+ end
+
+ def self.dependent_upon name
+ get_latest_gems.find_all { |gem|
+ gem.dependencies.any? { |dep| dep.name == name }
+ }
+ end
+
+
+ desc "List all the dependent gems of this gem"
+ task :list do
+ gems = self.get_gems_by_name
+ gem = gems[self.name]
+
+ abort "Couldn't find gem: #{self.name}" unless gem
+
+ deps = self.dependent_upon self.name
+ max = deps.map { |s| s.full_name.size }.max
+
+ puts " dependents:"
+ unless deps.empty? then
+ deps.sort_by { |spec| spec.full_name }.each do |spec|
+ vers = spec.dependencies.find {|s| s.name == name }.requirement_list
+ puts " %-*s - %s" % [max, spec.full_name, vers.join(", ")]
+ end
+ else
+ puts " none"
+ end
+ end
+
+ desc "Print a contact list for gems dependent on this gem"
+ task :email do
+ gems = self.get_gems_by_name
+ gem = gems[self.name]
+
+ abort "Couldn't find gem: #{self.name}" unless gem
+
+ deps = self.dependent_upon self.name
+
+ email = deps.map { |s| s.email }.flatten.sort.uniq
+ email = email.map { |s| s.split(/,\s*/) }.flatten.sort.uniq
+
+ email.map! { |s| # don't you people realize how easy this is?
+ s.gsub(/ at | _at_ |\s*(atmark|@nospam@|-at?-|@at?@|<at?>|\[at?\]|\(at?\))\s*/i, '@').gsub(/\s*(dot|\[d(ot)?\]|\.dot\.)\s*/i, '.').gsub(/\s+com$/, '.com')
+ }
+
+ bad, good = email.partition { |e| e !~ /^[\w.+-]+\@[\w.+-]+$/ }
+
+ warn "Rejecting #{bad.size} email. I couldn't unmunge them." unless
+ bad.empty?
+
+ puts good.join(", ")
+ end
+
+ desc "Fetch all the dependent gems of this gem into tarballs"
+ task :fetch do
+ gems = self.get_gems_by_name
+ gem = gems[self.name]
+ deps = self.dependent_upon self.name
+
+ mkdir "deps" unless File.directory? "deps"
+ Dir.chdir "deps" do
+ begin
+ deps.sort_by { |spec| spec.full_name }.each do |spec|
+ full_name = spec.full_name
+ tgz_name = "#{full_name}.tgz"
+ gem_name = "#{full_name}.gem"
+
+ next if File.exist? tgz_name
+ FileUtils.rm_rf [full_name, gem_name]
+
+ begin
+ warn "downloading #{full_name}"
+ Gem::RemoteFetcher.fetcher.download(spec, GEMURL, Dir.pwd)
+ FileUtils.mv "cache/#{gem_name}", '.'
+ rescue Gem::RemoteFetcher::FetchError
+ warn " failed"
+ next
+ end
+
+ warn "converting #{gem_name} to tarball"
+
+ system "gem unpack #{gem_name} 2> /dev/null"
+ system "gem spec -l #{gem_name} > #{full_name}/gemspec.rb"
+ system "tar zmcf #{tgz_name} #{full_name}"
+ FileUtils.rm_rf [full_name, gem_name, "cache"]
+ end
+ ensure
+ FileUtils.rm_rf "cache"
+ end
+ end
+ end
+ end
+
+ ############################################################
# Misc/Maintenance:
desc 'Run ZenTest against the package.'
task :audit do
libs = %w(lib test ext).join(File::PATH_SEPARATOR)
@@ -823,11 +970,12 @@
def run_tests(multi=false) # :nodoc:
msg = multi ? :sh : :ruby
cmd = if test ?f, 'test/test_all.rb' then
"#{RUBY_FLAGS} test/test_all.rb #{FILTER}"
else
- tests = ['test/unit'] + test_globs.map { |g| Dir.glob(g) }.flatten
+ tests = ["rubygems", self.testlib] +
+ test_globs.map { |g| Dir.glob(g) }.flatten
tests.map! {|f| %Q(require "#{f}")}
"#{RUBY_FLAGS} -e '#{tests.join("; ")}' #{FILTER}"
end
excludes = multiruby_skip.join(":")
@@ -860,7 +1008,13 @@
end
end
if $0 == __FILE__ then
out = `rake -T | egrep -v "redocs|repackage|clobber|trunk"`
- puts out.gsub(/\#/, '-').gsub(/^rake /, '# * ')
+ if ARGV.empty? then
+ # # default:: Run the default tasks.
+ puts out.gsub(/(\s*)\#/, '::\1').gsub(/^rake /, '# ')
+ else
+ # * default - Run the default tasks.
+ puts out.gsub(/\#/, '-').gsub(/^rake /, '* ')
+ end
end