File: deps.rb

package info (click to toggle)
ruby-hoe 3.22.1%2Bdfsg1-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 512 kB
  • sloc: ruby: 2,379; makefile: 5
file content (222 lines) | stat: -rw-r--r-- 5,798 bytes parent folder | download | duplicates (4)
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