1require 'rubygems/installer_test_case'
2
3class TestGemInstaller < Gem::InstallerTestCase
4
5  def setup
6    super
7
8    if __name__ =~ /^test_install(_|$)/ then
9      FileUtils.rm_r @spec.gem_dir
10      FileUtils.rm_r @user_spec.gem_dir
11    end
12
13    @config = Gem.configuration
14  end
15
16  def teardown
17    super
18
19    Gem.configuration = @config
20  end
21
22  def test_app_script_text
23    util_make_exec @spec, ''
24
25    expected = <<-EOF
26#!#{Gem.ruby}
27#
28# This file was generated by RubyGems.
29#
30# The application 'a' is installed as part of a gem, and
31# this file is here to facilitate running it.
32#
33
34require 'rubygems'
35
36version = \">= 0\"
37
38if ARGV.first
39  str = ARGV.first
40  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
41  if str =~ /\\A_(.*)_\\z/
42    version = $1
43    ARGV.shift
44  end
45end
46
47gem 'a', version
48load Gem.bin_path('a', 'executable', version)
49    EOF
50
51    wrapper = @installer.app_script_text 'executable'
52    assert_equal expected, wrapper
53  end
54
55  def test_build_extensions_none
56    use_ui @ui do
57      @installer.build_extensions
58    end
59
60    assert_equal '', @ui.output
61    assert_equal '', @ui.error
62
63    refute File.exist?('gem_make.out')
64  end
65
66  def test_build_extensions_extconf_bad
67    @installer.spec = @spec
68    @spec.extensions << 'extconf.rb'
69
70    e = assert_raises Gem::Installer::ExtensionBuildError do
71      use_ui @ui do
72        @installer.build_extensions
73      end
74    end
75
76    assert_match(/\AERROR: Failed to build gem native extension.$/, e.message)
77
78    assert_equal "Building native extensions.  This could take a while...\n",
79                 @ui.output
80    assert_equal '', @ui.error
81
82    gem_make_out = File.join @gemhome, 'gems', @spec.full_name, 'gem_make.out'
83
84    assert_match %r%#{Regexp.escape Gem.ruby} extconf\.rb%,
85                 File.read(gem_make_out)
86    assert_match %r%#{Regexp.escape Gem.ruby}: No such file%,
87                 File.read(gem_make_out)
88  end
89
90  def test_build_extensions_unsupported
91    @installer.spec = @spec
92    FileUtils.mkdir_p @spec.gem_dir
93    gem_make_out = File.join @spec.gem_dir, 'gem_make.out'
94    @spec.extensions << nil
95
96    e = assert_raises Gem::Installer::ExtensionBuildError do
97      use_ui @ui do
98        @installer.build_extensions
99      end
100    end
101
102    assert_match(/^\s*No builder for extension ''$/, e.message)
103
104    assert_equal "Building native extensions.  This could take a while...\n",
105                 @ui.output
106    assert_equal '', @ui.error
107
108    assert_equal "No builder for extension ''\n", File.read(gem_make_out)
109  ensure
110    FileUtils.rm_f gem_make_out
111  end
112
113  def test_build_extensions_with_build_args
114    args = ["--aa", "--bb"]
115    @installer.build_args = args
116    @installer.spec = @spec
117    @spec.extensions << 'extconf.rb'
118
119    File.open File.join(@spec.gem_dir, "extconf.rb"), "w" do |f|
120      f.write <<-'RUBY'
121        puts "IN EXTCONF"
122        extconf_args = File.join File.dirname(__FILE__), 'extconf_args'
123        File.open extconf_args, 'w' do |f|
124          f.puts ARGV.inspect
125        end
126
127        File.open 'Makefile', 'w' do |f|
128          f.puts "default:\n\techo built"
129          f.puts "install:\n\techo installed"
130        end
131      RUBY
132    end
133
134    use_ui @ui do
135      @installer.build_extensions
136    end
137
138    path = File.join @spec.gem_dir, "extconf_args"
139
140    assert_equal args.inspect, File.read(path).strip
141    assert File.directory? File.join(@spec.gem_dir, 'lib')
142  end
143
144  def test_check_executable_overwrite
145    @installer.generate_bin
146
147    @spec = Gem::Specification.new do |s|
148      s.files = ['lib/code.rb']
149      s.name = "a"
150      s.version = "3"
151      s.summary = "summary"
152      s.description = "desc"
153      s.require_path = 'lib'
154    end
155
156    util_make_exec
157    @installer.gem_dir = util_gem_dir @spec
158    @installer.wrappers = true
159    @installer.generate_bin
160
161    installed_exec = File.join util_inst_bindir, 'executable'
162    assert File.exist? installed_exec
163
164    wrapper = File.read installed_exec
165    assert_match %r|generated by RubyGems|, wrapper
166  end
167
168  def test_check_executable_overwrite_default_bin_dir
169    if defined?(RUBY_FRAMEWORK_VERSION)
170      orig_RUBY_FRAMEWORK_VERSION = RUBY_FRAMEWORK_VERSION
171      Object.send :remove_const, :RUBY_FRAMEWORK_VERSION
172    end
173    orig_bindir = Gem::ConfigMap[:bindir]
174    Gem::ConfigMap[:bindir] = Gem.bindir
175
176    util_conflict_executable false
177
178    ui = Gem::MockGemUi.new "n\n"
179    use_ui ui do
180      e = assert_raises Gem::InstallError do
181        @installer.generate_bin
182      end
183
184      conflicted = File.join @gemhome, 'bin', 'executable'
185      assert_match %r%\A"executable" from a conflicts with (?:#{Regexp.quote(conflicted)}|installed executable from conflict)\z%,
186                   e.message
187    end
188  ensure
189    Object.const_set :RUBY_FRAMEWORK_VERSION, orig_RUBY_FRAMEWORK_VERSION if
190      orig_RUBY_FRAMEWORK_VERSION
191    Gem::ConfigMap[:bindir] = orig_bindir
192  end
193
194  def test_check_executable_overwrite_format_executable
195    @installer.generate_bin
196
197    @spec = Gem::Specification.new do |s|
198      s.files = ['lib/code.rb']
199      s.name = "a"
200      s.version = "3"
201      s.summary = "summary"
202      s.description = "desc"
203      s.require_path = 'lib'
204    end
205
206    open File.join(util_inst_bindir, 'executable'), 'w' do |io|
207     io.write <<-EXEC
208#!/usr/local/bin/ruby
209#
210# This file was generated by RubyGems
211
212gem 'other', version
213     EXEC
214    end
215
216    util_make_exec
217    Gem::Installer.exec_format = 'foo-%s-bar'
218    @installer.gem_dir = @spec.gem_dir
219    @installer.wrappers = true
220    @installer.format_executable = true
221
222    @installer.generate_bin # should not raise
223
224    installed_exec = File.join util_inst_bindir, 'foo-executable-bar'
225    assert File.exist? installed_exec
226
227    wrapper = File.read installed_exec
228    assert_match %r|generated by RubyGems|, wrapper
229  end
230
231  def test_check_executable_overwrite_other_gem
232    util_conflict_executable true
233
234    ui = Gem::MockGemUi.new "n\n"
235
236    use_ui ui do
237      e = assert_raises Gem::InstallError do
238        @installer.generate_bin
239      end
240
241      assert_equal '"executable" from a conflicts with installed executable from conflict',
242                   e.message
243    end
244  end
245
246  def test_check_executable_overwrite_other_gem_force
247    util_conflict_executable true
248    @installer.wrappers = true
249    @installer.force = true
250
251    @installer.generate_bin
252
253    installed_exec = File.join util_inst_bindir, 'executable'
254    assert File.exist? installed_exec
255
256    wrapper = File.read installed_exec
257    assert_match %r|generated by RubyGems|, wrapper
258  end
259
260  def test_check_executable_overwrite_other_non_gem
261    util_conflict_executable false
262    @installer.wrappers = true
263
264    @installer.generate_bin
265
266    installed_exec = File.join util_inst_bindir, 'executable'
267    assert File.exist? installed_exec
268
269    wrapper = File.read installed_exec
270    assert_match %r|generated by RubyGems|, wrapper
271  end unless Gem.win_platform?
272
273  def test_ensure_dependency
274    quick_spec 'a'
275
276    dep = Gem::Dependency.new 'a', '>= 2'
277    assert @installer.ensure_dependency(@spec, dep)
278
279    dep = Gem::Dependency.new 'b', '> 2'
280    e = assert_raises Gem::InstallError do
281      @installer.ensure_dependency @spec, dep
282    end
283
284    assert_equal 'a requires b (> 2)', e.message
285  end
286
287  def test_ensure_loadable_spec
288    a, a_gem = util_gem 'a', 2 do |s|
289      s.add_dependency 'garbage ~> 5'
290    end
291
292    installer = Gem::Installer.new a_gem
293
294    e = assert_raises Gem::InstallError do
295      installer.ensure_loadable_spec
296    end
297
298    assert_equal "The specification for #{a.full_name} is corrupt " +
299                 "(SyntaxError)", e.message
300  end
301
302  def test_ensure_loadable_spec_security_policy
303    _, a_gem = util_gem 'a', 2 do |s|
304      s.add_dependency 'garbage ~> 5'
305    end
306
307    policy = Gem::Security::HighSecurity
308    installer = Gem::Installer.new a_gem, :security_policy => policy
309
310    assert_raises Gem::Security::Exception do
311      installer.ensure_loadable_spec
312    end
313  end
314
315  def test_extract_files
316    @installer.extract_files
317
318    assert_path_exists File.join util_gem_dir, 'bin/executable'
319  end
320
321  def test_generate_bin_bindir
322    @installer.wrappers = true
323
324    @spec.executables = %w[executable]
325    @spec.bindir = '.'
326
327    exec_file = @installer.formatted_program_filename 'executable'
328    exec_path = File.join util_gem_dir(@spec), exec_file
329    File.open exec_path, 'w' do |f|
330      f.puts '#!/usr/bin/ruby'
331    end
332
333    @installer.gem_dir = util_gem_dir
334
335    @installer.generate_bin
336
337    assert_equal true, File.directory?(util_inst_bindir)
338    installed_exec = File.join(util_inst_bindir, 'executable')
339    assert_equal true, File.exist?(installed_exec)
340    assert_equal mask, File.stat(installed_exec).mode unless win_platform?
341
342    wrapper = File.read installed_exec
343    assert_match %r|generated by RubyGems|, wrapper
344  end
345
346  def test_generate_bin_bindir_with_user_install_warning
347    bin_dir = Gem.win_platform? ? File.expand_path(ENV["WINDIR"]).upcase :
348                                  "/usr/bin"
349
350    options = {
351      :bin_dir => bin_dir,
352      :install_dir => "/non/existant"
353    }
354
355    inst = Gem::Installer.new '', options
356
357    Gem::Installer.path_warning = false
358
359    use_ui @ui do
360      inst.check_that_user_bin_dir_is_in_path
361    end
362
363    assert_equal "", @ui.error
364  end
365
366  def test_generate_bin_script
367    @installer.wrappers = true
368    util_make_exec
369    @installer.gem_dir = util_gem_dir
370
371    @installer.generate_bin
372    assert File.directory? util_inst_bindir
373    installed_exec = File.join util_inst_bindir, 'executable'
374    assert File.exist? installed_exec
375    assert_equal mask, File.stat(installed_exec).mode unless win_platform?
376
377    wrapper = File.read installed_exec
378    assert_match %r|generated by RubyGems|, wrapper
379  end
380
381  def test_generate_bin_script_format
382    @installer.format_executable = true
383    @installer.wrappers = true
384    util_make_exec
385    @installer.gem_dir = util_gem_dir
386
387    Gem::Installer.exec_format = 'foo-%s-bar'
388    @installer.generate_bin
389    assert_equal true, File.directory?(util_inst_bindir)
390    installed_exec = File.join util_inst_bindir, 'foo-executable-bar'
391    assert_equal true, File.exist?(installed_exec)
392  ensure
393    Gem::Installer.exec_format = nil
394  end
395
396  def test_generate_bin_script_format_disabled
397    @installer.wrappers = true
398    util_make_exec
399    @installer.gem_dir = util_gem_dir
400
401    Gem::Installer.exec_format = 'foo-%s-bar'
402    @installer.generate_bin
403    assert_equal true, File.directory?(util_inst_bindir)
404    installed_exec = File.join util_inst_bindir, 'executable'
405    assert_equal true, File.exist?(installed_exec)
406  ensure
407    Gem::Installer.exec_format = nil
408  end
409
410  def test_generate_bin_script_install_dir
411    @installer.wrappers = true
412
413    gem_dir = File.join("#{@gemhome}2", "gems", @spec.full_name)
414    gem_bindir = File.join gem_dir, 'bin'
415    FileUtils.mkdir_p gem_bindir
416    File.open File.join(gem_bindir, 'executable'), 'w' do |f|
417      f.puts "#!/bin/ruby"
418    end
419
420    @installer.gem_home = "#{@gemhome}2"
421    @installer.gem_dir = gem_dir
422    @installer.bin_dir = File.join "#{@gemhome}2", 'bin'
423
424    @installer.generate_bin
425
426    installed_exec = File.join("#{@gemhome}2", "bin", 'executable')
427    assert File.exist? installed_exec
428    assert_equal mask, File.stat(installed_exec).mode unless win_platform?
429
430    wrapper = File.read installed_exec
431    assert_match %r|generated by RubyGems|, wrapper
432  end
433
434  def test_generate_bin_script_no_execs
435    util_execless
436
437    @installer.wrappers = true
438    @installer.generate_bin
439
440    refute File.exist?(util_inst_bindir), 'bin dir was created when not needed'
441  end
442
443  def test_generate_bin_script_no_perms
444    @installer.wrappers = true
445    util_make_exec
446
447    Dir.mkdir util_inst_bindir
448
449    if win_platform?
450      skip('test_generate_bin_script_no_perms skipped on MS Windows')
451    else
452      FileUtils.chmod 0000, util_inst_bindir
453
454      assert_raises Gem::FilePermissionError do
455        @installer.generate_bin
456      end
457    end
458  ensure
459    FileUtils.chmod 0755, util_inst_bindir unless ($DEBUG or win_platform?)
460  end
461
462  def test_generate_bin_script_no_shebang
463    @installer.wrappers = true
464    @spec.executables = %w[executable]
465
466    gem_dir = File.join @gemhome, 'gems', @spec.full_name
467    gem_bindir = File.join gem_dir, 'bin'
468    FileUtils.mkdir_p gem_bindir
469    File.open File.join(gem_bindir, 'executable'), 'w' do |f|
470      f.puts "blah blah blah"
471    end
472
473    @installer.generate_bin
474
475    installed_exec = File.join @gemhome, 'bin', 'executable'
476    assert_equal true, File.exist?(installed_exec)
477    assert_equal mask, File.stat(installed_exec).mode unless win_platform?
478
479    wrapper = File.read installed_exec
480    assert_match %r|generated by RubyGems|, wrapper
481    # HACK some gems don't have #! in their executables, restore 2008/06
482    #assert_no_match %r|generated by RubyGems|, wrapper
483  end
484
485  def test_generate_bin_script_wrappers
486    @installer.wrappers = true
487    util_make_exec
488    @installer.gem_dir = util_gem_dir
489    installed_exec = File.join(util_inst_bindir, 'executable')
490
491    real_exec = File.join util_gem_dir, 'bin', 'executable'
492
493    # fake --no-wrappers for previous install
494    unless Gem.win_platform? then
495      FileUtils.mkdir_p File.dirname(installed_exec)
496      FileUtils.ln_s real_exec, installed_exec
497    end
498
499    @installer.generate_bin
500    assert_equal true, File.directory?(util_inst_bindir)
501    assert_equal true, File.exist?(installed_exec)
502    assert_equal mask, File.stat(installed_exec).mode unless win_platform?
503
504    assert_match %r|generated by RubyGems|, File.read(installed_exec)
505
506    refute_match %r|generated by RubyGems|, File.read(real_exec),
507                 'real executable overwritten'
508  end
509
510  def test_generate_bin_symlink
511    return if win_platform? #Windows FS do not support symlinks
512
513    @installer.wrappers = false
514    util_make_exec
515    @installer.gem_dir = util_gem_dir
516
517    @installer.generate_bin
518    assert_equal true, File.directory?(util_inst_bindir)
519    installed_exec = File.join util_inst_bindir, 'executable'
520    assert_equal true, File.symlink?(installed_exec)
521    assert_equal(File.join(util_gem_dir, 'bin', 'executable'),
522                 File.readlink(installed_exec))
523  end
524
525  def test_generate_bin_symlink_no_execs
526    util_execless
527
528    @installer.wrappers = false
529    @installer.generate_bin
530
531    refute File.exist?(util_inst_bindir)
532  end
533
534  def test_generate_bin_symlink_no_perms
535    @installer.wrappers = false
536    util_make_exec
537    @installer.gem_dir = util_gem_dir
538
539    Dir.mkdir util_inst_bindir
540
541    if win_platform?
542      skip('test_generate_bin_symlink_no_perms skipped on MS Windows')
543    else
544      FileUtils.chmod 0000, util_inst_bindir
545
546      assert_raises Gem::FilePermissionError do
547        @installer.generate_bin
548      end
549    end
550  ensure
551    FileUtils.chmod 0755, util_inst_bindir unless ($DEBUG or win_platform?)
552  end
553
554  def test_generate_bin_symlink_update_newer
555    return if win_platform? #Windows FS do not support symlinks
556
557    @installer.wrappers = false
558    util_make_exec
559    @installer.gem_dir = util_gem_dir
560
561    @installer.generate_bin
562    installed_exec = File.join(util_inst_bindir, 'executable')
563    assert_equal(File.join(util_gem_dir, 'bin', 'executable'),
564                 File.readlink(installed_exec))
565
566    @spec = Gem::Specification.new do |s|
567      s.files = ['lib/code.rb']
568      s.name = "a"
569      s.version = "3"
570      s.summary = "summary"
571      s.description = "desc"
572      s.require_path = 'lib'
573    end
574
575    util_make_exec
576    @installer.gem_dir = util_gem_dir @spec
577    @installer.generate_bin
578    installed_exec = File.join(util_inst_bindir, 'executable')
579    assert_equal(@spec.bin_file('executable'),
580                 File.readlink(installed_exec),
581                 "Ensure symlink moved to latest version")
582  end
583
584  def test_generate_bin_symlink_update_older
585    return if win_platform? #Windows FS do not support symlinks
586
587    @installer.wrappers = false
588    util_make_exec
589    @installer.gem_dir = util_gem_dir
590
591    @installer.generate_bin
592    installed_exec = File.join(util_inst_bindir, 'executable')
593    assert_equal(File.join(util_gem_dir, 'bin', 'executable'),
594                 File.readlink(installed_exec))
595
596    spec = Gem::Specification.new do |s|
597      s.files = ['lib/code.rb']
598      s.name = "a"
599      s.version = "1"
600      s.summary = "summary"
601      s.description = "desc"
602      s.require_path = 'lib'
603    end
604
605    util_make_exec
606    one = @spec.dup
607    one.version = 1
608    @installer.gem_dir = util_gem_dir one
609    @installer.spec = spec
610
611    @installer.generate_bin
612
613    installed_exec = File.join util_inst_bindir, 'executable'
614    expected = File.join util_gem_dir, 'bin', 'executable'
615    assert_equal(expected,
616                 File.readlink(installed_exec),
617                 "Ensure symlink not moved")
618  end
619
620  def test_generate_bin_symlink_update_remove_wrapper
621    return if win_platform? #Windows FS do not support symlinks
622
623    @installer.wrappers = true
624    util_make_exec
625    @installer.gem_dir = util_gem_dir
626
627    @installer.generate_bin
628
629    installed_exec = File.join util_inst_bindir, 'executable'
630    assert File.exist? installed_exec
631
632    @spec = Gem::Specification.new do |s|
633      s.files = ['lib/code.rb']
634      s.name = "a"
635      s.version = "3"
636      s.summary = "summary"
637      s.description = "desc"
638      s.require_path = 'lib'
639    end
640    util_make_exec
641
642    util_installer @spec, @gemhome
643    @installer.wrappers = false
644    @installer.gem_dir = util_gem_dir
645
646    @installer.generate_bin
647
648    installed_exec = File.join util_inst_bindir, 'executable'
649    assert_equal(@spec.bin_file('executable'),
650                 File.readlink(installed_exec),
651                 "Ensure symlink moved to latest version")
652  end
653
654  def test_generate_bin_symlink_win32
655    old_win_platform = Gem.win_platform?
656    Gem.win_platform = true
657    @installer.wrappers = false
658    util_make_exec
659    @installer.gem_dir = util_gem_dir
660
661    use_ui @ui do
662      @installer.generate_bin
663    end
664
665    assert_equal true, File.directory?(util_inst_bindir)
666    installed_exec = File.join(util_inst_bindir, 'executable')
667    assert_equal true, File.exist?(installed_exec)
668
669    assert_match(/Unable to use symlinks on Windows, installing wrapper/i,
670                 @ui.error)
671
672    wrapper = File.read installed_exec
673    assert_match(/generated by RubyGems/, wrapper)
674  ensure
675    Gem.win_platform = old_win_platform
676  end
677
678  def test_generate_bin_uses_default_shebang
679    return if win_platform? #Windows FS do not support symlinks
680
681    @installer.wrappers = true
682    util_make_exec
683
684    @installer.generate_bin
685
686    default_shebang = Gem.ruby
687    shebang_line = open("#{@gemhome}/bin/executable") { |f| f.readlines.first }
688    assert_match(/\A#!/, shebang_line)
689    assert_match(/#{default_shebang}/, shebang_line)
690  end
691
692  def test_initialize
693    spec = quick_spec 'a' do |s| s.platform = Gem::Platform.new 'mswin32' end
694    gem = File.join @tempdir, spec.file_name
695
696    Dir.mkdir util_inst_bindir
697    util_build_gem spec
698    FileUtils.mv spec.cache_file, @tempdir
699
700    installer = Gem::Installer.new gem
701
702    assert_equal File.join(@gemhome, 'gems', spec.full_name), installer.gem_dir
703    assert_equal File.join(@gemhome, 'bin'), installer.bin_dir
704  end
705
706  def test_initialize_user_install
707    installer = Gem::Installer.new @gem, :user_install => true
708
709    assert_equal File.join(Gem.user_dir, 'gems', @spec.full_name),
710                 installer.gem_dir
711    assert_equal Gem.bindir(Gem.user_dir), installer.bin_dir
712  end
713
714  def test_initialize_user_install_bin_dir
715    installer =
716      Gem::Installer.new @gem, :user_install => true, :bin_dir => @tempdir
717
718    assert_equal File.join(Gem.user_dir, 'gems', @spec.full_name),
719                 installer.gem_dir
720    assert_equal @tempdir, installer.bin_dir
721  end
722
723  def test_install
724    Dir.mkdir util_inst_bindir
725    util_setup_gem
726    util_clear_gems
727
728    gemdir     = File.join @gemhome, 'gems', @spec.full_name
729    cache_file = File.join @gemhome, 'cache', @spec.file_name
730    stub_exe   = File.join @gemhome, 'bin', 'executable'
731    rakefile   = File.join gemdir, 'ext', 'a', 'Rakefile'
732
733    Gem.pre_install do |installer|
734      refute File.exist?(cache_file), 'cache file must not exist yet'
735      true
736    end
737
738    Gem.post_build do |installer|
739      assert File.exist?(gemdir), 'gem install dir must exist'
740      assert File.exist?(rakefile), 'gem executable must exist'
741      refute File.exist?(stub_exe), 'gem executable must not exist'
742      true
743    end
744
745    Gem.post_install do |installer|
746      assert File.exist?(cache_file), 'cache file must exist'
747    end
748
749    @newspec = nil
750    build_rake_in do
751      use_ui @ui do
752        @newspec = @installer.install
753      end
754    end
755
756    assert_equal @spec, @newspec
757    assert File.exist? gemdir
758    assert File.exist?(stub_exe), 'gem executable must exist'
759
760    exe = File.join gemdir, 'bin', 'executable'
761    assert File.exist? exe
762
763    exe_mode = File.stat(exe).mode & 0111
764    assert_equal 0111, exe_mode, "0%o" % exe_mode unless win_platform?
765
766    assert File.exist?(File.join(gemdir, 'lib', 'code.rb'))
767
768    assert File.exist? rakefile
769
770    spec_file = File.join(@gemhome, 'specifications', @spec.spec_name)
771
772    assert_equal spec_file, @newspec.loaded_from
773    assert File.exist?(spec_file)
774
775    assert_same @installer, @post_build_hook_arg
776    assert_same @installer, @post_install_hook_arg
777    assert_same @installer, @pre_install_hook_arg
778  end
779
780  def test_install_creates_working_binstub
781    Dir.mkdir util_inst_bindir
782    util_setup_gem
783    util_clear_gems
784
785    @installer.wrappers = true
786
787    gemdir = File.join @gemhome, 'gems', @spec.full_name
788
789    @newspec = nil
790    build_rake_in do
791      use_ui @ui do
792        @newspec = @installer.install
793      end
794    end
795
796    exe = File.join gemdir, 'bin', 'executable'
797
798    e = assert_raises RuntimeError do
799      instance_eval File.read(exe)
800    end
801
802    assert_match(/ran executable/, e.message)
803  end
804
805  def test_install_creates_binstub_that_understand_version
806    Dir.mkdir util_inst_bindir
807    util_setup_gem
808    util_clear_gems
809
810    @installer.wrappers = true
811
812    @newspec = nil
813    build_rake_in do
814      use_ui @ui do
815        @newspec = @installer.install
816      end
817    end
818
819    exe = File.join @gemhome, 'bin', 'executable'
820
821    ARGV.unshift "_3.0_"
822
823    begin
824      Gem::Specification.reset
825
826      e = assert_raises Gem::LoadError do
827        instance_eval File.read(exe)
828      end
829    ensure
830      ARGV.shift if ARGV.first == "_3.0_"
831    end
832
833    assert_match(/\(= 3\.0\)/, e.message)
834  end
835
836  def test_install_creates_binstub_that_dont_trust_encoding
837    skip unless "".respond_to?(:force_encoding)
838
839    Dir.mkdir util_inst_bindir
840    util_setup_gem
841    util_clear_gems
842
843    @installer.wrappers = true
844
845    @newspec = nil
846    build_rake_in do
847      use_ui @ui do
848        @newspec = @installer.install
849      end
850    end
851
852    exe = File.join @gemhome, 'bin', 'executable'
853
854    extra_arg = "\xE4pfel".force_encoding("UTF-8")
855    ARGV.unshift extra_arg
856
857    begin
858      Gem::Specification.reset
859
860      e = assert_raises RuntimeError do
861        instance_eval File.read(exe)
862      end
863    ensure
864      ARGV.shift if ARGV.first == extra_arg
865    end
866
867    assert_match(/ran executable/, e.message)
868  end
869
870  def test_install_with_no_prior_files
871    Dir.mkdir util_inst_bindir
872    util_clear_gems
873
874    util_setup_gem
875    build_rake_in do
876      use_ui @ui do
877        assert_equal @spec, @installer.install
878      end
879    end
880
881    gemdir = File.join(@gemhome, 'gems', @spec.full_name)
882    assert File.exist?(File.join(gemdir, 'lib', 'code.rb'))
883
884    util_setup_gem
885    # Morph spec to have lib/other.rb instead of code.rb and recreate
886    @spec.files = File.join('lib', 'other.rb')
887    Dir.chdir @tempdir do
888      File.open File.join('lib', 'other.rb'), 'w' do |f| f.puts '1' end
889      use_ui ui do
890        FileUtils.rm @gem
891        Gem::Package.build @spec
892      end
893    end
894    @installer = Gem::Installer.new @gem
895    build_rake_in do
896      use_ui @ui do
897        assert_equal @spec, @installer.install
898      end
899    end
900
901    assert File.exist?(File.join(gemdir, 'lib', 'other.rb'))
902    refute(File.exist?(File.join(gemdir, 'lib', 'code.rb')),
903           "code.rb from prior install of same gem shouldn't remain here")
904  end
905
906  def test_install_force
907    use_ui @ui do
908      installer = Gem::Installer.new old_ruby_required, :force => true
909      installer.install
910    end
911
912    gem_dir = File.join(@gemhome, 'gems', 'old_ruby_required-1')
913    assert File.exist?(gem_dir)
914  end
915
916  def test_install_missing_dirs
917    FileUtils.rm_f File.join(Gem.dir, 'cache')
918    FileUtils.rm_f File.join(Gem.dir, 'docs')
919    FileUtils.rm_f File.join(Gem.dir, 'specifications')
920
921    use_ui @ui do
922      @installer.install
923    end
924
925    File.directory? File.join(Gem.dir, 'cache')
926    File.directory? File.join(Gem.dir, 'docs')
927    File.directory? File.join(Gem.dir, 'specifications')
928
929    assert File.exist?(File.join(@gemhome, 'cache', @spec.file_name))
930    assert File.exist?(File.join(@gemhome, 'specifications', @spec.spec_name))
931  end
932
933  def test_install_post_build_false
934    util_clear_gems
935
936    Gem.post_build do
937      false
938    end
939
940    use_ui @ui do
941      e = assert_raises Gem::InstallError do
942        @installer.install
943      end
944
945      location = "#{__FILE__}:#{__LINE__ - 9}"
946
947      assert_equal "post-build hook at #{location} failed for a-2", e.message
948    end
949
950    spec_file = File.join @gemhome, 'specifications', @spec.spec_name
951    refute File.exist? spec_file
952
953    gem_dir = File.join @gemhome, 'gems', @spec.full_name
954    refute File.exist? gem_dir
955  end
956
957  def test_install_post_build_nil
958    util_clear_gems
959
960    Gem.post_build do
961      nil
962    end
963
964    use_ui @ui do
965      @installer.install
966    end
967
968    spec_file = File.join @gemhome, 'specifications', @spec.spec_name
969    assert File.exist? spec_file
970
971    gem_dir = File.join @gemhome, 'gems', @spec.full_name
972    assert File.exist? gem_dir
973  end
974
975  def test_install_pre_install_false
976    util_clear_gems
977
978    Gem.pre_install do
979      false
980    end
981
982    use_ui @ui do
983      e = assert_raises Gem::InstallError do
984        @installer.install
985      end
986
987      location = "#{__FILE__}:#{__LINE__ - 9}"
988
989      assert_equal "pre-install hook at #{location} failed for a-2", e.message
990    end
991
992    spec_file = File.join @gemhome, 'specifications', @spec.spec_name
993    refute File.exist? spec_file
994  end
995
996  def test_install_pre_install_nil
997    util_clear_gems
998
999    Gem.pre_install do
1000      nil
1001    end
1002
1003    use_ui @ui do
1004      @installer.install
1005    end
1006
1007    spec_file = File.join @gemhome, 'specifications', @spec.spec_name
1008    assert File.exist? spec_file
1009  end
1010
1011  def test_install_with_message
1012    @spec.post_install_message = 'I am a shiny gem!'
1013
1014    use_ui @ui do
1015      path = Gem::Package.build @spec
1016
1017      @installer = Gem::Installer.new path
1018      @installer.install
1019    end
1020
1021    assert_match %r|I am a shiny gem!|, @ui.output
1022  end
1023
1024  def test_install_extension_and_script
1025    @spec.extensions << "extconf.rb"
1026    write_file File.join(@tempdir, "extconf.rb") do |io|
1027      io.write <<-RUBY
1028        require "mkmf"
1029        create_makefile("#{@spec.name}")
1030      RUBY
1031    end
1032
1033    rb = File.join("lib", "#{@spec.name}.rb")
1034    @spec.files += [rb]
1035    write_file File.join(@tempdir, rb) do |io|
1036      io.write <<-RUBY
1037        # #{@spec.name}.rb
1038      RUBY
1039    end
1040
1041    Dir.mkdir(File.join("lib", @spec.name))
1042    rb2 = File.join("lib", @spec.name, "#{@spec.name}.rb")
1043    @spec.files << rb2
1044    write_file File.join(@tempdir, rb2) do |io|
1045      io.write <<-RUBY
1046        # #{@spec.name}/#{@spec.name}.rb
1047      RUBY
1048    end
1049
1050    assert !File.exist?(File.join(@spec.gem_dir, rb))
1051    assert !File.exist?(File.join(@spec.gem_dir, rb2))
1052    use_ui @ui do
1053      path = Gem::Package.build @spec
1054
1055      @installer = Gem::Installer.new path
1056      @installer.install
1057    end
1058    assert File.exist?(File.join(@spec.gem_dir, rb))
1059    assert File.exist?(File.join(@spec.gem_dir, rb2))
1060  end
1061
1062  def test_install_extension_flat
1063    skip '1.9.2 and earlier mkmf.rb does not create TOUCH' if
1064      RUBY_VERSION < '1.9.3'
1065
1066    @spec.require_paths = ["."]
1067
1068    @spec.extensions << "extconf.rb"
1069
1070    write_file File.join(@tempdir, "extconf.rb") do |io|
1071      io.write <<-RUBY
1072        require "mkmf"
1073
1074        CONFIG['CC'] = '$(TOUCH) $@ ||'
1075        CONFIG['LDSHARED'] = '$(TOUCH) $@ ||'
1076        $ruby = '#{Gem.ruby}'
1077
1078        create_makefile("#{@spec.name}")
1079      RUBY
1080    end
1081
1082    # empty depend file for no auto dependencies
1083    @spec.files += %W"depend #{@spec.name}.c".each {|file|
1084      write_file File.join(@tempdir, file)
1085    }
1086
1087    so = File.join(@spec.gem_dir, "#{@spec.name}.#{RbConfig::CONFIG["DLEXT"]}")
1088    assert !File.exist?(so)
1089    use_ui @ui do
1090      path = Gem::Package.build @spec
1091
1092      @installer = Gem::Installer.new path
1093      @installer.install
1094    end
1095    assert File.exist?(so)
1096  rescue
1097    puts '-' * 78
1098    puts File.read File.join(@gemhome, 'gems', 'a-2', 'Makefile')
1099    puts '-' * 78
1100    puts File.read File.join(@gemhome, 'gems', 'a-2', 'gem_make.out')
1101    puts '-' * 78
1102    raise
1103  end
1104
1105  def test_installation_satisfies_dependency_eh
1106    quick_spec 'a'
1107
1108    dep = Gem::Dependency.new 'a', '>= 2'
1109    assert @installer.installation_satisfies_dependency?(dep)
1110
1111    dep = Gem::Dependency.new 'a', '> 2'
1112    refute @installer.installation_satisfies_dependency?(dep)
1113  end
1114
1115  def test_pre_install_checks_dependencies
1116    @spec.add_dependency 'b', '> 5'
1117    util_setup_gem
1118
1119    use_ui @ui do
1120      assert_raises Gem::InstallError do
1121        @installer.install
1122      end
1123    end
1124  end
1125
1126  def test_pre_install_checks_dependencies_ignore
1127    @spec.add_dependency 'b', '> 5'
1128    @installer.ignore_dependencies = true
1129
1130    build_rake_in do
1131      use_ui @ui do
1132        assert @installer.pre_install_checks
1133      end
1134    end
1135  end
1136
1137  def test_pre_install_checks_dependencies_install_dir
1138    gemhome2 = "#{@gemhome}2"
1139    @spec.add_dependency 'd'
1140
1141    quick_gem 'd', 2
1142
1143    gem = File.join @gemhome, @spec.file_name
1144
1145    FileUtils.mv @gemhome, gemhome2
1146    FileUtils.mkdir @gemhome
1147
1148    FileUtils.mv File.join(gemhome2, 'cache', @spec.file_name), gem
1149
1150    # Don't leak any already activated gems into the installer, require
1151    # that it work everything out on it's own.
1152    Gem::Specification.reset
1153
1154    installer = Gem::Installer.new gem, :install_dir => gemhome2
1155
1156    build_rake_in do
1157      use_ui @ui do
1158        assert installer.pre_install_checks
1159      end
1160    end
1161  end
1162
1163  def test_pre_install_checks_ruby_version
1164    use_ui @ui do
1165      installer = Gem::Installer.new old_ruby_required
1166      e = assert_raises Gem::InstallError do
1167        installer.pre_install_checks
1168      end
1169      assert_equal 'old_ruby_required requires Ruby version = 1.4.6.',
1170                   e.message
1171    end
1172  end
1173
1174  def test_pre_install_checks_wrong_rubygems_version
1175    spec = quick_spec 'old_rubygems_required', '1' do |s|
1176      s.required_rubygems_version = '< 0'
1177    end
1178
1179    util_build_gem spec
1180
1181    gem = File.join(@gemhome, 'cache', spec.file_name)
1182
1183    use_ui @ui do
1184      @installer = Gem::Installer.new gem
1185      e = assert_raises Gem::InstallError do
1186        @installer.pre_install_checks
1187      end
1188      assert_equal 'old_rubygems_required requires RubyGems version < 0. ' +
1189        "Try 'gem update --system' to update RubyGems itself.", e.message
1190    end
1191  end
1192
1193  def test_shebang
1194    util_make_exec @spec, "#!/usr/bin/ruby"
1195
1196    shebang = @installer.shebang 'executable'
1197
1198    assert_equal "#!#{Gem.ruby}", shebang
1199  end
1200
1201  def test_shebang_arguments
1202    util_make_exec @spec, "#!/usr/bin/ruby -ws"
1203
1204    shebang = @installer.shebang 'executable'
1205
1206    assert_equal "#!#{Gem.ruby} -ws", shebang
1207  end
1208
1209  def test_shebang_empty
1210    util_make_exec @spec, ''
1211
1212    shebang = @installer.shebang 'executable'
1213    assert_equal "#!#{Gem.ruby}", shebang
1214  end
1215
1216  def test_shebang_env
1217    util_make_exec @spec, "#!/usr/bin/env ruby"
1218
1219    shebang = @installer.shebang 'executable'
1220
1221    assert_equal "#!#{Gem.ruby}", shebang
1222  end
1223
1224  def test_shebang_env_arguments
1225    util_make_exec @spec, "#!/usr/bin/env ruby -ws"
1226
1227    shebang = @installer.shebang 'executable'
1228
1229    assert_equal "#!#{Gem.ruby} -ws", shebang
1230  end
1231
1232  def test_shebang_env_shebang
1233    util_make_exec @spec, ''
1234    @installer.env_shebang = true
1235
1236    shebang = @installer.shebang 'executable'
1237
1238    env_shebang = "/usr/bin/env" unless Gem.win_platform?
1239
1240    assert_equal("#!#{env_shebang} #{Gem::ConfigMap[:ruby_install_name]}",
1241                 shebang)
1242  end
1243
1244  def test_shebang_nested
1245    util_make_exec @spec, "#!/opt/local/ruby/bin/ruby"
1246
1247    shebang = @installer.shebang 'executable'
1248
1249    assert_equal "#!#{Gem.ruby}", shebang
1250  end
1251
1252  def test_shebang_nested_arguments
1253    util_make_exec @spec, "#!/opt/local/ruby/bin/ruby -ws"
1254
1255    shebang = @installer.shebang 'executable'
1256
1257    assert_equal "#!#{Gem.ruby} -ws", shebang
1258  end
1259
1260  def test_shebang_version
1261    util_make_exec @spec, "#!/usr/bin/ruby18"
1262
1263    shebang = @installer.shebang 'executable'
1264
1265    assert_equal "#!#{Gem.ruby}", shebang
1266  end
1267
1268  def test_shebang_version_arguments
1269    util_make_exec @spec, "#!/usr/bin/ruby18 -ws"
1270
1271    shebang = @installer.shebang 'executable'
1272
1273    assert_equal "#!#{Gem.ruby} -ws", shebang
1274  end
1275
1276  def test_shebang_version_env
1277    util_make_exec @spec, "#!/usr/bin/env ruby18"
1278
1279    shebang = @installer.shebang 'executable'
1280
1281    assert_equal "#!#{Gem.ruby}", shebang
1282  end
1283
1284  def test_shebang_version_env_arguments
1285    util_make_exec @spec, "#!/usr/bin/env ruby18 -ws"
1286
1287    shebang = @installer.shebang 'executable'
1288
1289    assert_equal "#!#{Gem.ruby} -ws", shebang
1290  end
1291
1292  def test_shebang_custom
1293    conf = Gem::ConfigFile.new []
1294    conf[:custom_shebang] = 'test'
1295
1296    Gem.configuration = conf
1297
1298    util_make_exec @spec, "#!/usr/bin/ruby"
1299
1300    shebang = @installer.shebang 'executable'
1301
1302    assert_equal "#!test", shebang
1303  end
1304
1305  def test_shebang_custom_with_expands
1306    bin_env = win_platform? ? '' : '/usr/bin/env'
1307    conf = Gem::ConfigFile.new []
1308    conf[:custom_shebang] = '1 $env 2 $ruby 3 $exec 4 $name'
1309
1310    Gem.configuration = conf
1311
1312    util_make_exec @spec, "#!/usr/bin/ruby"
1313
1314    shebang = @installer.shebang 'executable'
1315
1316    assert_equal "#!1 #{bin_env} 2 #{Gem.ruby} 3 executable 4 a", shebang
1317  end
1318
1319  def test_shebang_custom_with_expands_and_arguments
1320    bin_env = win_platform? ? '' : '/usr/bin/env'
1321    conf = Gem::ConfigFile.new []
1322    conf[:custom_shebang] = '1 $env 2 $ruby 3 $exec'
1323
1324    Gem.configuration = conf
1325
1326    util_make_exec @spec, "#!/usr/bin/ruby -ws"
1327
1328    shebang = @installer.shebang 'executable'
1329
1330    assert_equal "#!1 #{bin_env} 2 #{Gem.ruby} -ws 3 executable", shebang
1331  end
1332
1333  def test_unpack
1334    util_setup_gem
1335
1336    dest = File.join @gemhome, 'gems', @spec.full_name
1337
1338    @installer.unpack dest
1339
1340    assert File.exist?(File.join(dest, 'lib', 'code.rb'))
1341    assert File.exist?(File.join(dest, 'bin', 'executable'))
1342  end
1343
1344  def test_write_build_args
1345    refute_path_exists @spec.build_info_file
1346
1347    @installer.build_args = %w[
1348      --with-libyaml-dir /usr/local/Cellar/libyaml/0.1.4
1349    ]
1350
1351    @installer.write_build_info_file
1352
1353    assert_path_exists @spec.build_info_file
1354
1355    expected = "--with-libyaml-dir\n/usr/local/Cellar/libyaml/0.1.4\n"
1356
1357    assert_equal expected, File.read(@spec.build_info_file)
1358  end
1359
1360  def test_write_build_args_empty
1361    refute_path_exists @spec.build_info_file
1362
1363    @installer.write_build_info_file
1364
1365    refute_path_exists @spec.build_info_file
1366  end
1367
1368  def test_write_build_info_file_install_dir
1369    installer = Gem::Installer.new @gem, :install_dir => "#{@gemhome}2"
1370
1371    installer.build_args = %w[
1372      --with-libyaml-dir /usr/local/Cellar/libyaml/0.1.4
1373    ]
1374
1375    installer.write_build_info_file
1376
1377    refute_path_exists @spec.build_info_file
1378    assert_path_exists \
1379      File.join("#{@gemhome}2", 'build_info', "#{@spec.full_name}.info")
1380  end
1381
1382  def test_write_cache_file
1383    cache_file = File.join @gemhome, 'cache', @spec.file_name
1384    gem = File.join @gemhome, @spec.file_name
1385
1386    FileUtils.mv cache_file, gem
1387    refute_path_exists cache_file
1388
1389    installer = Gem::Installer.new gem
1390    installer.spec = @spec
1391    installer.gem_home = @gemhome
1392
1393    installer.write_cache_file
1394
1395    assert_path_exists cache_file
1396  end
1397
1398  def test_write_spec
1399    FileUtils.rm @spec.spec_file
1400    refute File.exist?(@spec.spec_file)
1401
1402    @installer.spec = @spec
1403    @installer.gem_home = @gemhome
1404
1405    @installer.write_spec
1406
1407    assert File.exist?(@spec.spec_file)
1408    assert_equal @spec, eval(File.read(@spec.spec_file))
1409  end
1410
1411  def test_write_spec_writes_cached_spec
1412    FileUtils.rm @spec.spec_file
1413    refute File.exist?(@spec.spec_file)
1414
1415    @spec.files = %w[a.rb b.rb c.rb]
1416
1417    @installer.spec = @spec
1418    @installer.gem_home = @gemhome
1419
1420    @installer.write_spec
1421
1422    # cached specs have no file manifest:
1423    @spec.files = []
1424
1425    assert_equal @spec, eval(File.read(@spec.spec_file))
1426  end
1427
1428  def test_dir
1429    assert_match %r!/gemhome/gems/a-2$!, @installer.dir
1430  end
1431
1432  def old_ruby_required
1433    spec = quick_spec 'old_ruby_required', '1' do |s|
1434      s.required_ruby_version = '= 1.4.6'
1435    end
1436
1437    util_build_gem spec
1438
1439    spec.cache_file
1440  end
1441
1442  def util_execless
1443    @spec = quick_spec 'z'
1444    util_build_gem @spec
1445
1446    @installer = util_installer @spec, @gemhome
1447  end
1448
1449  def util_conflict_executable wrappers
1450    conflict = quick_gem 'conflict' do |spec|
1451      util_make_exec spec
1452    end
1453
1454    util_build_gem conflict
1455
1456    installer = util_installer conflict, @gemhome
1457    installer.wrappers = wrappers
1458    installer.generate_bin
1459  end
1460
1461  def mask
1462    0100755 & (~File.umask)
1463  end
1464end
1465