Removed obsolete bin scripts.
[rbx.git] / test / rubygems / gemutilities.rb
blob967e3dc34d10ba60864d9a8b7966bce53e4902d8
1 #!/usr/bin/env ruby
2 #--
3 # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
4 # All rights reserved.
5 # See LICENSE.txt for permissions.
6 #++
8 at_exit { $SAFE = 1 }
10 require 'fileutils'
11 require 'test/unit'
12 require 'tmpdir'
13 require 'tempfile'
14 require 'uri'
15 require 'rubygems/source_info_cache'
16 require 'rubygems/package'
18 require File.join(File.expand_path(File.dirname(__FILE__)), 'mockgemui')
20 module Gem
21   def self.source_index=(si)
22     @@source_index = si
23   end
25   def self.win_platform=(val)
26     @@win_platform = val
27   end
28 end
30 class FakeFetcher
32   attr_reader :data
33   attr_accessor :uri
34   attr_accessor :paths
36   def initialize
37     @data = {}
38     @paths = []
39     @uri = nil
40   end
42   def fetch_path(path)
43     path = path.to_s
44     @paths << path
45     raise ArgumentError, 'need full URI' unless path =~ %r'^http://'
46     data = @data[path]
47     raise Gem::RemoteFetcher::FetchError, "no data for #{path}" if data.nil?
48     data.respond_to?(:call) ? data.call : data
49   end
51   def fetch_size(path)
52     path = path.to_s
53     @paths << path
54     raise ArgumentError, 'need full URI' unless path =~ %r'^http://'
55     data = @data[path]
56     raise Gem::RemoteFetcher::FetchError, "no data for #{path}" if data.nil?
57     data.respond_to?(:call) ? data.call : data.length
58   end
60   def download spec, source_uri, install_dir = Gem.dir
61     name = "#{spec.full_name}.gem"
62     path = File.join(install_dir, 'cache', name)
64     Gem.ensure_gem_subdirectories install_dir
66     if source_uri =~ /^http/ then
67       File.open(path, "wb") do |f|
68         f.write fetch_path(File.join(source_uri, "gems", name))
69       end
70     else
71       FileUtils.cp source_uri, path
72     end
74     path
75   end
76 end
78 class RubyGemTestCase < Test::Unit::TestCase
80   include Gem::DefaultUserInteraction
82   undef_method :default_test if instance_methods.include? 'default_test' or
83                                 instance_methods.include? :default_test
85   def setup
86     super
88     @ui = MockGemUi.new
89     tmpdir = nil
90     Dir.chdir Dir.tmpdir do tmpdir = Dir.pwd end # HACK OSX /private/tmp
91     @tempdir = File.join tmpdir, "test_rubygems_#{$$}"
92     @tempdir.untaint
93     @gemhome = File.join @tempdir, "gemhome"
94     @gemcache = File.join(@gemhome, "source_cache")
95     @usrcache = File.join(@gemhome, ".gem", "user_cache")
96     @latest_usrcache = File.join(@gemhome, ".gem", "latest_user_cache")
98     FileUtils.mkdir_p @gemhome
100     ENV['GEMCACHE'] = @usrcache
101     Gem.use_paths(@gemhome)
102     Gem.loaded_specs.clear
104     Gem.configuration.verbose = true
105     Gem.configuration.update_sources = true
107     @gem_repo = "http://gems.example.com"
108     Gem.sources.replace [@gem_repo]
110     @orig_BASERUBY = Gem::ConfigMap[:BASERUBY]
111     Gem::ConfigMap[:BASERUBY] = Gem::ConfigMap[:RUBY_INSTALL_NAME]
113     @orig_arch = Gem::ConfigMap[:arch]
115     if win_platform?
116       util_set_arch 'i386-mswin32'
117     else
118       util_set_arch 'i686-darwin8.10.1'
119     end
121     @marshal_version = "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}"
123     @private_key = File.expand_path File.join(File.dirname(__FILE__),
124                                               'private_key.pem')
125     @public_cert = File.expand_path File.join(File.dirname(__FILE__),
126                                               'public_cert.pem')
127   end
129   def teardown
130     Gem::ConfigMap[:BASERUBY] = @orig_BASERUBY
131     Gem::ConfigMap[:arch] = @orig_arch
133     if defined? Gem::RemoteFetcher then
134       Gem::RemoteFetcher.instance_variable_set :@fetcher, nil
135     end
137     FileUtils.rm_rf @tempdir
139     ENV.delete 'GEMCACHE'
140     ENV.delete 'GEM_HOME'
141     ENV.delete 'GEM_PATH'
143     Gem.clear_paths
144     Gem::SourceInfoCache.instance_variable_set :@cache, nil
145   end
147   def install_gem gem
148     require 'rubygems/installer'
150     use_ui MockGemUi.new do
151       Dir.chdir @tempdir do
152         Gem::Builder.new(gem).build
153       end
154     end
156     gem = File.join(@tempdir, "#{gem.full_name}.gem").untaint
157     Gem::Installer.new(gem).install
158   end
160   def prep_cache_files(lc)
161     @usr_si ||= Gem::SourceIndex.new
162     @usr_sice ||= Gem::SourceInfoCacheEntry.new @usr_si, 0
164     @sys_si ||= Gem::SourceIndex.new
165     @sys_sice ||= Gem::SourceInfoCacheEntry.new @sys_si, 0
167     latest_si = Gem::SourceIndex.new
168     latest_si.add_specs(*@sys_si.latest_specs)
169     latest_sys_sice = Gem::SourceInfoCacheEntry.new latest_si, 0
171     latest_si = Gem::SourceIndex.new
172     latest_si.add_specs(*@usr_si.latest_specs)
173     latest_usr_sice = Gem::SourceInfoCacheEntry.new latest_si, 0
175     [ [lc.system_cache_file, @sys_sice],
176       [lc.latest_system_cache_file, latest_sys_sice],
177       [lc.user_cache_file, @usr_sice],
178       [lc.latest_user_cache_file, latest_usr_sice],
179     ].each do |filename, data|
180       FileUtils.mkdir_p File.dirname(filename).untaint
182       open filename.dup.untaint, 'wb' do |f|
183         f.write Marshal.dump({ @gem_repo => data })
184       end
185     end
186   end
188   def read_cache(path)
189     open path.dup.untaint, 'rb' do |io|
190       Marshal.load io.read
191     end
192   end
194   def read_binary(path)
195     Gem.read_binary path
196   end
198   def write_file(path)
199     path = File.join(@gemhome, path)
200     dir = File.dirname path
201     FileUtils.mkdir_p dir
203     open path, 'wb' do |io|
204       yield io
205     end
207     path
208   end
210   def quick_gem(gemname, version='2')
211     require 'rubygems/specification'
213     spec = Gem::Specification.new do |s|
214       s.platform = Gem::Platform::RUBY
215       s.name = gemname
216       s.version = version
217       s.author = 'A User'
218       s.email = 'example@example.com'
219       s.homepage = 'http://example.com'
220       s.has_rdoc = true
221       s.summary = "this is a summary"
222       s.description = "This is a test description"
224       yield(s) if block_given?
225     end
227     path = File.join "specifications", "#{spec.full_name}.gemspec"
228     written_path = write_file path do |io|
229       io.write(spec.to_ruby)
230     end
232     spec.loaded_from = written_path
234     return spec
235   end
237   def util_build_gem(spec)
238     dir = File.join(@gemhome, 'gems', spec.full_name)
239     FileUtils.mkdir_p dir
241     Dir.chdir dir do
242       spec.files.each do |file|
243         next if File.exist? file
244         FileUtils.mkdir_p File.dirname(file)
245         File.open file, 'w' do |fp| fp.puts "# #{file}" end
246       end
248       use_ui MockGemUi.new do
249         Gem::Builder.new(spec).build
250       end
252       FileUtils.mv "#{spec.full_name}.gem",
253                    File.join(@gemhome, 'cache', "#{spec.original_name}.gem")
254     end
255   end
257   def util_gem(name, version, &block)
258     spec = quick_gem(name, version, &block)
260     util_build_gem spec
262     cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem"
263     FileUtils.mv File.join(@gemhome, 'cache', "#{spec.original_name}.gem"),
264                  cache_file
265     FileUtils.rm File.join(@gemhome, 'specifications',
266                            "#{spec.full_name}.gemspec")
268     spec.loaded_from = nil
269     spec.loaded = false
271     [spec, cache_file]
272   end
274   def util_make_gems
275     init = proc do |s|
276       s.files = %w[lib/code.rb]
277       s.require_paths = %w[lib]
278     end
280     @a1 = quick_gem('a', '1', &init)
281     @a2 = quick_gem('a', '2', &init)
282     @a_evil9 = quick_gem('a_evil', '9', &init)
283     @b2 = quick_gem('b', '2', &init)
284     @c1_2   = quick_gem('c', '1.2',   &init)
285     @pl1     = quick_gem 'pl', '1' do |s| # l for legacy
286       s.files = %w[lib/code.rb]
287       s.require_paths = %w[lib]
288       s.platform = Gem::Platform.new 'i386-linux'
289       s.instance_variable_set :@original_platform, 'i386-linux'
290     end
292     write_file File.join(*%W[gems #{@a1.original_name} lib code.rb]) do end
293     write_file File.join(*%W[gems #{@a2.original_name} lib code.rb]) do end
294     write_file File.join(*%W[gems #{@b2.original_name} lib code.rb]) do end
295     write_file File.join(*%W[gems #{@c1_2.original_name} lib code.rb]) do end
296     write_file File.join(*%W[gems #{@pl1.original_name} lib code.rb]) do end
298     [@a1, @a2, @a_evil9, @b2, @c1_2, @pl1].each { |spec| util_build_gem spec }
300     FileUtils.rm_r File.join(@gemhome, 'gems', @pl1.original_name)
302     Gem.source_index = nil
303   end
305   ##
306   # Set the platform to +cpu+ and +os+
308   def util_set_arch(arch)
309     Gem::ConfigMap[:arch] = arch
310     platform = Gem::Platform.new arch
312     Gem.instance_variable_set :@platforms, nil
313     Gem::Platform.instance_variable_set :@local, nil
315     platform
316   end
318   def util_setup_fake_fetcher
319     require 'zlib'
320     require 'socket'
321     require 'rubygems/remote_fetcher'
323     @uri = URI.parse @gem_repo
324     @fetcher = FakeFetcher.new
325     @fetcher.uri = @uri
327     util_make_gems
329     @all_gems = [@a1, @a2, @a_evil9, @b2, @c1_2].sort
330     @all_gem_names = @all_gems.map { |gem| gem.full_name }
332     gem_names = [@a1.full_name, @a2.full_name, @b2.full_name]
333     @gem_names = gem_names.sort.join("\n")
335     @source_index = Gem::SourceIndex.new
336     @source_index.add_spec @a1
337     @source_index.add_spec @a2
338     @source_index.add_spec @a_evil9
339     @source_index.add_spec @c1_2
341     Gem::RemoteFetcher.instance_variable_set :@fetcher, @fetcher
342   end
344   def util_setup_source_info_cache(*specs)
345     require 'rubygems/source_info_cache_entry'
347     specs = Hash[*specs.map { |spec| [spec.full_name, spec] }.flatten]
348     si = Gem::SourceIndex.new specs
350     sice = Gem::SourceInfoCacheEntry.new si, 0
351     sic = Gem::SourceInfoCache.new
353     sic.set_cache_data( { @gem_repo => sice } )
354     sic.update
355     sic.write_cache
356     sic.reset_cache_data
358     Gem::SourceInfoCache.instance_variable_set :@cache, sic
359     si
360   end
362   def util_zip(data)
363     Zlib::Deflate.deflate data
364   end
366   def self.win_platform?
367     Gem.win_platform?
368   end
370   def win_platform?
371     Gem.win_platform?
372   end
374   # NOTE Allow tests to use a random (but controlled) port number instead of
375   # a hardcoded one. This helps CI tools when running parallels builds on
376   # the same builder slave.
377   def self.process_based_port
378     @@process_based_port ||= 8000 + $$ % 1000
379   end
381   def process_based_port
382     self.class.process_based_port
383   end
387 class TempIO
389   @@count = 0
391   def initialize(string = '')
392     @tempfile = Tempfile.new "TempIO-#{@@count ++ 1}"
393     @tempfile.binmode
394     @tempfile.write string
395     @tempfile.rewind
396   end
398   def method_missing(meth, *args, &block)
399     @tempfile.send(meth, *args, &block)
400   end
402   def respond_to?(meth)
403     @tempfile.respond_to? meth
404   end
406   def string
407     @tempfile.flush
409     Gem.read_binary @tempfile.path
410   end