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