1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
|
require "rubygems/remote_fetcher"
require "uri"
##
# Deps plugin for hoe.
#
# === Tasks Provided:
#
# check_extra_deps:: Install missing dependencies.
# 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
module Hoe::Deps
##
# The main rubygems repository.
GEMURL = URI.parse "http://rubygems.org"
##
# Define tasks for plugin.
def define_deps_tasks
namespace :deps do
desc "List all the dependent gems of this gem"
task :list do
deps_list_task
end
desc "Print a contact list for gems dependent on this gem"
task :email do
deps_email_task
end
desc "Fetch all the dependent gems of this gem into tarballs"
task :fetch do
deps_fetch_task
end
end
desc "Install missing dependencies."
task :check_extra_deps do
check_extra_deps_task
end
desc "Install missing plugins."
task :install_plugins do
install_missing_plugins
end
end
def check_extra_deps_task # :nodoc:
(extra_deps + extra_dev_deps).each do |dep|
begin
gem(*dep)
rescue Gem::LoadError
name, req, = dep
install_gem name, req, false
gem(*dep)
end
end
end
def deps_list_task # :nodoc:
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(&:full_name).each do |spec|
vers = spec.dependencies.find { |s| s.name == name }.requirements_list
puts " %-*s - %s" % [max, spec.full_name, vers.join(", ")]
end
else
puts " none"
end
end
def deps_email_task # :nodoc:
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(&:email).compact.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(", ")
warn "Warning: couldn't extract any email addresses" if good.empty?
end
def deps_fetch_task # :nodoc:
deps = self.dependent_upon self.name
mkdir "deps" unless File.directory? "deps"
Dir.chdir "deps" do
begin
deps.sort_by(&: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
##
# Return the rubygems source index.
def get_source_index
@@index ||= nil
return @@index if @@index
dump = unless File.exist? ".source_index" then
warn "Fetching full index and caching. This can take a while."
url = GEMURL + "Marshal.#{Gem.marshal_version}.Z"
dump = Gem::RemoteFetcher.fetcher.fetch_path url
dump = Gem.inflate dump
warn "stripping index to latest gems"
ary = Marshal.load dump
h = {}
Hash[ary].values.sort.each { |spec| h[spec.name] = spec }
ary = h.map { |_, v| [v.full_name, v] }
dump = Marshal.dump ary
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
##
# Return the latest rubygems.
def get_latest_gems
@@cache ||= Hash[*get_source_index.flatten].values
end
##
# Return a hash of the latest rubygems keyed by name.
def get_gems_by_name
@@by_name ||= Hash[*get_latest_gems.map { |gem|
[gem.name, gem, gem.full_name, gem]
}.flatten]
end
##
# Installs plugins that aren't currently installed
def install_missing_plugins plugins = Hoe.bad_plugins
version = ">= 0"
plugins.each do |name|
dash_name = name.to_s.gsub "_", "-"
next if have_gem?("hoe-#{name}") or
have_gem?(name) or
have_gem?(dash_name)
install_gem("hoe-#{name}", version, false) or
install_gem(name, version, false) or
install_gem(dash_name, version, false) or
warn "could not install gem for #{name} plugin"
end
end
##
# Return all the dependencies on the named rubygem.
def dependent_upon name
get_latest_gems.find_all { |gem|
gem.dependencies.any? { |dep| dep.name == name }
}
end
end
|