1# -*- coding: utf-8 -*- 2#-- 3# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. 4# All rights reserved. 5# See LICENSE.txt for permissions. 6#++ 7 8require 'rubygems/version' 9require 'rubygems/requirement' 10require 'rubygems/platform' 11require 'rubygems/deprecate' 12 13# :stopdoc: 14# date.rb can't be loaded for `make install` due to miniruby 15# Date is needed for old gems that stored #date as Date instead of Time. 16class Date; end 17# :startdoc: 18 19## 20# The Specification class contains the information for a Gem. Typically 21# defined in a .gemspec file or a Rakefile, and looks like this: 22# 23# Gem::Specification.new do |s| 24# s.name = 'example' 25# s.version = '0.1.0' 26# s.summary = "This is an example!" 27# s.description = "Much longer explanation of the example!" 28# s.authors = ["Ruby Coder"] 29# s.email = 'rubycoder@example.com' 30# s.files = ["lib/example.rb"] 31# s.homepage = 'https://rubygems.org/gems/example' 32# end 33# 34# Starting in RubyGems 1.9.0, a Specification can hold arbitrary 35# metadata. This metadata is accessed via Specification#metadata 36# and has the following restrictions: 37# 38# * Must be a Hash object 39# * All keys and values must be Strings 40# * Keys can be a maximum of 128 bytes and values can be a 41# maximum of 1024 bytes 42# * All strings must be UTF8, no binary data is allowed 43# 44# For example, to add metadata for the location of a bugtracker: 45# 46# s.metadata = { "bugtracker" => "http://somewhere.com/blah" } 47 48class Gem::Specification 49 50 # REFACTOR: Consider breaking out this version stuff into a separate 51 # module. There's enough special stuff around it that it may justify 52 # a separate class. 53 54 ## 55 # The version number of a specification that does not specify one 56 # (i.e. RubyGems 0.7 or earlier). 57 58 NONEXISTENT_SPECIFICATION_VERSION = -1 59 60 ## 61 # The specification version applied to any new Specification instances 62 # created. This should be bumped whenever something in the spec format 63 # changes. 64 # 65 # Specification Version History: 66 # 67 # spec ruby 68 # ver ver yyyy-mm-dd description 69 # -1 <0.8.0 pre-spec-version-history 70 # 1 0.8.0 2004-08-01 Deprecated "test_suite_file" for "test_files" 71 # "test_file=x" is a shortcut for "test_files=[x]" 72 # 2 0.9.5 2007-10-01 Added "required_rubygems_version" 73 # Now forward-compatible with future versions 74 # 3 1.3.2 2009-01-03 Added Fixnum validation to specification_version 75 # 4 1.9.0 2011-06-07 Added metadata 76 #-- 77 # When updating this number, be sure to also update #to_ruby. 78 # 79 # NOTE RubyGems < 1.2 cannot load specification versions > 2. 80 81 CURRENT_SPECIFICATION_VERSION = 4 82 83 ## 84 # An informal list of changes to the specification. The highest-valued 85 # key should be equal to the CURRENT_SPECIFICATION_VERSION. 86 87 SPECIFICATION_VERSION_HISTORY = { 88 -1 => ['(RubyGems versions up to and including 0.7 did not have versioned specifications)'], 89 1 => [ 90 'Deprecated "test_suite_file" in favor of the new, but equivalent, "test_files"', 91 '"test_file=x" is a shortcut for "test_files=[x]"' 92 ], 93 2 => [ 94 'Added "required_rubygems_version"', 95 'Now forward-compatible with future versions', 96 ], 97 3 => [ 98 'Added Fixnum validation to the specification_version' 99 ], 100 4 => [ 101 'Added sandboxed freeform metadata to the specification version.' 102 ] 103 } 104 105 MARSHAL_FIELDS = { -1 => 16, 1 => 16, 2 => 16, 3 => 17, 4 => 18 } 106 107 today = Time.now.utc 108 TODAY = Time.utc(today.year, today.month, today.day) 109 110 # :startdoc: 111 112 ## 113 # List of attribute names: [:name, :version, ...] 114 115 @@required_attributes = [:rubygems_version, 116 :specification_version, 117 :name, 118 :version, 119 :date, 120 :summary, 121 :require_paths] 122 123 ## 124 # Map of attribute names to default values. 125 126 @@default_value = { 127 :authors => [], 128 :autorequire => nil, 129 :bindir => 'bin', 130 :cert_chain => [], 131 :date => TODAY, 132 :dependencies => [], 133 :description => nil, 134 :email => nil, 135 :executables => [], 136 :extensions => [], 137 :extra_rdoc_files => [], 138 :files => [], 139 :homepage => nil, 140 :licenses => [], 141 :metadata => {}, 142 :name => nil, 143 :platform => Gem::Platform::RUBY, 144 :post_install_message => nil, 145 :rdoc_options => [], 146 :require_paths => ['lib'], 147 :required_ruby_version => Gem::Requirement.default, 148 :required_rubygems_version => Gem::Requirement.default, 149 :requirements => [], 150 :rubyforge_project => nil, 151 :rubygems_version => Gem::VERSION, 152 :signing_key => nil, 153 :specification_version => CURRENT_SPECIFICATION_VERSION, 154 :summary => nil, 155 :test_files => [], 156 :version => nil, 157 } 158 159 @@attributes = @@default_value.keys.sort_by { |s| s.to_s } 160 @@array_attributes = @@default_value.reject { |k,v| v != [] }.keys 161 @@nil_attributes, @@non_nil_attributes = @@default_value.keys.partition { |k| 162 @@default_value[k].nil? 163 } 164 165 ###################################################################### 166 # :section: Required gemspec attributes 167 168 ## 169 # This gem's name. 170 # 171 # Usage: 172 # 173 # spec.name = 'rake' 174 175 attr_accessor :name 176 177 ## 178 # This gem's version. 179 # 180 # The version string can contain numbers and periods, such as +1.0.0+. 181 # A gem is a 'prerelease' gem if the version has a letter in it, such as 182 # +1.0.0.pre+. 183 # 184 # Usage: 185 # 186 # spec.version = '0.4.1' 187 188 attr_reader :version 189 190 ## 191 # Paths in the gem to add to <code>$LOAD_PATH</code> when this gem is 192 # activated. 193 # 194 # If you have an extension you do not need to add <code>"ext"</code> to the 195 # require path, the extension build process will copy the extension files 196 # into "lib" for you. 197 # 198 # The default value is <code>"lib"</code> 199 # 200 # Usage: 201 # 202 # # If all library files are in the root directory... 203 # spec.require_path = '.' 204 205 attr_accessor :require_paths 206 207 ## 208 # The version of RubyGems used to create this gem. 209 # 210 # Do not set this, it is set automatically when the gem is packaged. 211 212 attr_accessor :rubygems_version 213 214 ## 215 # A short summary of this gem's description. Displayed in `gem list -d`. 216 # 217 # The #description should be more detailed than the summary. 218 # 219 # Usage: 220 # 221 # spec.summary = "This is a small summary of my gem" 222 223 attr_reader :summary 224 225 ## 226 # The platform this gem runs on. 227 # 228 # This is usually Gem::Platform::RUBY or Gem::Platform::CURRENT. 229 # 230 # Most gems contain pure Ruby code; they should simply leave the default 231 # value in place. Some gems contain C (or other) code to be compiled into a 232 # Ruby "extension". The should leave the default value in place unless 233 # their code will only compile on a certain type of system. Some gems 234 # consist of pre-compiled code ("binary gems"). It's especially important 235 # that they set the platform attribute appropriately. A shortcut is to set 236 # the platform to Gem::Platform::CURRENT, which will cause the gem builder 237 # to set the platform to the appropriate value for the system on which the 238 # build is being performed. 239 # 240 # If this attribute is set to a non-default value, it will be included in 241 # the filename of the gem when it is built such as: 242 # nokogiri-1.6.0-x86-mingw32.gem 243 # 244 # Usage: 245 # 246 # spec.platform = Gem::Platform.local 247 248 def platform= platform 249 if @original_platform.nil? or 250 @original_platform == Gem::Platform::RUBY then 251 @original_platform = platform 252 end 253 254 case platform 255 when Gem::Platform::CURRENT then 256 @new_platform = Gem::Platform.local 257 @original_platform = @new_platform.to_s 258 259 when Gem::Platform then 260 @new_platform = platform 261 262 # legacy constants 263 when nil, Gem::Platform::RUBY then 264 @new_platform = Gem::Platform::RUBY 265 when 'mswin32' then # was Gem::Platform::WIN32 266 @new_platform = Gem::Platform.new 'x86-mswin32' 267 when 'i586-linux' then # was Gem::Platform::LINUX_586 268 @new_platform = Gem::Platform.new 'x86-linux' 269 when 'powerpc-darwin' then # was Gem::Platform::DARWIN 270 @new_platform = Gem::Platform.new 'ppc-darwin' 271 else 272 @new_platform = Gem::Platform.new platform 273 end 274 275 @platform = @new_platform.to_s 276 277 invalidate_memoized_attributes 278 279 @new_platform 280 end 281 282 ## 283 # Files included in this gem. You cannot append to this accessor, you must 284 # assign to it. 285 # 286 # Only add files you can require to this list, not directories, etc. 287 # 288 # Directories are automatically stripped from this list when building a gem, 289 # other non-files cause an error. 290 # 291 # Usage: 292 # 293 # require 'rake' 294 # spec.files = FileList['lib/**/*.rb', 295 # 'bin/*', 296 # '[A-Z]*', 297 # 'test/**/*'].to_a 298 # 299 # # or without Rake... 300 # spec.files = Dir['lib/**/*.rb'] + Dir['bin/*'] 301 # spec.files += Dir['[A-Z]*'] + Dir['test/**/*'] 302 # spec.files.reject! { |fn| fn.include? "CVS" } 303 304 def files 305 # DO NOT CHANGE TO ||= ! This is not a normal accessor. (yes, it sucks) 306 # DOC: Why isn't it normal? Why does it suck? How can we fix this? 307 @files = [@files, 308 @test_files, 309 add_bindir(@executables), 310 @extra_rdoc_files, 311 @extensions, 312 ].flatten.uniq.compact 313 end 314 315 ###################################################################### 316 # :section: Optional gemspec attributes 317 318 ## 319 # The path in the gem for executable scripts. Usually 'bin' 320 # 321 # Usage: 322 # 323 # spec.bindir = 'bin' 324 325 attr_accessor :bindir 326 327 ## 328 # The certificate chain used to sign this gem. See Gem::Security for 329 # details. 330 331 attr_accessor :cert_chain 332 333 ## 334 # A long description of this gem 335 # 336 # The description should be more detailed than the summary. 337 # 338 # Usage: 339 # 340 # spec.description = <<-EOF 341 # Rake is a Make-like program implemented in Ruby. Tasks and 342 # dependencies are specified in standard Ruby syntax. 343 # EOF 344 345 attr_reader :description 346 347 ## 348 # A contact email address (or addresses) for this gem 349 # 350 # Usage: 351 # 352 # spec.email = 'john.jones@example.com' 353 # spec.email = ['jack@example.com', 'jill@example.com'] 354 355 attr_accessor :email 356 357 ## 358 # The URL of this gem's home page 359 # 360 # Usage: 361 # 362 # spec.homepage = 'http://rake.rubyforge.org' 363 364 attr_accessor :homepage 365 366 ## 367 # A message that gets displayed after the gem is installed. 368 # 369 # Usage: 370 # 371 # spec.post_install_message = "Thanks for installing!" 372 373 attr_accessor :post_install_message 374 375 ## 376 # The key used to sign this gem. See Gem::Security for details. 377 378 attr_accessor :signing_key 379 380 ## 381 # :attr_accessor: metadata 382 # 383 # Arbitrary metadata for this gem. An instance of Hash. 384 # 385 # metadata is simply a Symbol => String association that contains arbitary 386 # data that could be useful to other consumers. 387 388 attr_accessor :metadata 389 390 ## 391 # Adds a development dependency named +gem+ with +requirements+ to this 392 # gem. 393 # 394 # Usage: 395 # 396 # spec.add_development_dependency 'example', '~> 1.1', '>= 1.1.4' 397 # 398 # Development dependencies aren't installed by default and aren't 399 # activated when a gem is required. 400 401 def add_development_dependency(gem, *requirements) 402 add_dependency_with_type(gem, :development, *requirements) 403 end 404 405 ## 406 # Adds a runtime dependency named +gem+ with +requirements+ to this gem. 407 # 408 # Usage: 409 # 410 # spec.add_runtime_dependency 'example', '~> 1.1', '>= 1.1.4' 411 412 def add_runtime_dependency(gem, *requirements) 413 add_dependency_with_type(gem, :runtime, *requirements) 414 end 415 416 ## 417 # Singular writer for #authors 418 # 419 # Usage: 420 # 421 # spec.author = 'John Jones' 422 423 def author= o 424 self.authors = [o] 425 end 426 427 ## 428 # Sets the list of authors, ensuring it is an array. 429 # 430 # Usage: 431 # 432 # spec.authors = ['John Jones', 'Mary Smith'] 433 434 def authors= value 435 @authors = Array(value).flatten.grep(String) 436 end 437 438 ## 439 # Executables included in the gem. 440 # 441 # For example, the rake gem has rake as an executable. You don’t specify the 442 # full path (as in bin/rake); all application-style files are expected to be 443 # found in bindir. These files must be executable ruby files. Files that 444 # use bash or other interpreters will not work. 445 # 446 # Usage: 447 # 448 # spec.executables << 'rake' 449 450 def executables 451 @executables ||= [] 452 end 453 454 ## 455 # Extensions to build when installing the gem, specifically the paths to 456 # extconf.rb-style files used to compile extensions. 457 # 458 # These files will be run when the gem is installed, causing the C (or 459 # whatever) code to be compiled on the user’s machine. 460 # 461 # Usage: 462 # 463 # spec.extensions << 'ext/rmagic/extconf.rb' 464 # 465 # See Gem::Ext::Builder for information about writing extensions for gems. 466 467 def extensions 468 @extensions ||= [] 469 end 470 471 ## 472 # Extra files to add to RDoc such as README or doc/examples.txt 473 # 474 # When the user elects to generate the RDoc documentation for a gem (typically 475 # at install time), all the library files are sent to RDoc for processing. 476 # This option allows you to have some non-code files included for a more 477 # complete set of documentation. 478 # 479 # Usage: 480 # 481 # spec.extra_rdoc_files = ['README', 'doc/user-guide.txt'] 482 483 def extra_rdoc_files 484 @extra_rdoc_files ||= [] 485 end 486 487 ## 488 # The license for this gem. 489 # 490 # The license must be a short name, no more than 64 characters. 491 # 492 # This should just be the name of your license. The full 493 # text of the license should be inside of the gem when you build it. 494 # 495 # You can set multiple licenses with #licenses= 496 # 497 # Usage: 498 # spec.license = 'MIT' 499 500 def license=o 501 self.licenses = [o] 502 end 503 504 ## 505 # The license(s) for the library. 506 # 507 # Each license must be a short name, no more than 64 characters. 508 # 509 # This should just be the name of your license. The full 510 # text of the license should be inside of the gem when you build it. 511 # 512 # Usage: 513 # spec.licenses = ['MIT', 'GPL-2'] 514 515 def licenses= licenses 516 @licenses = Array licenses 517 end 518 519 ## 520 # Specifies the rdoc options to be used when generating API documentation. 521 # 522 # Usage: 523 # 524 # spec.rdoc_options << '--title' << 'Rake -- Ruby Make' << 525 # '--main' << 'README' << 526 # '--line-numbers' 527 528 def rdoc_options 529 @rdoc_options ||= [] 530 end 531 532 ## 533 # The version of Ruby required by this gem. The ruby version can be 534 # specified to the patch-level: 535 # 536 # $ ruby -v -e 'p Gem.ruby_version' 537 # ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.4.0] 538 # #<Gem::Version "2.0.0.247"> 539 # 540 # Usage: 541 # 542 # # This gem will work with 1.8.6 or greater... 543 # spec.required_ruby_version = '>= 1.8.6' 544 # 545 # # Only with ruby 2.0.x 546 # spec.required_ruby_version = '~> 2.0' 547 548 def required_ruby_version= req 549 @required_ruby_version = Gem::Requirement.create req 550 end 551 552 ## 553 # Lists the external (to RubyGems) requirements that must be met for this gem 554 # to work. It's simply information for the user. 555 # 556 # Usage: 557 # 558 # spec.requirements << 'libmagick, v6.0' 559 # spec.requirements << 'A good graphics card' 560 561 def requirements 562 @requirements ||= [] 563 end 564 565 ## 566 # A collection of unit test files. They will be loaded as unit tests when 567 # the user requests a gem to be unit tested. 568 # 569 # Usage: 570 # spec.test_files = Dir.glob('test/tc_*.rb') 571 # spec.test_files = ['tests/test-suite.rb'] 572 573 def test_files= files 574 @test_files = Array files 575 end 576 577 ###################################################################### 578 # :section: Specification internals 579 580 ## 581 # True when this gemspec has been activated. This attribute is not persisted. 582 583 attr_accessor :activated 584 585 alias :activated? :activated 586 587 ## 588 # Autorequire was used by old RubyGems to automatically require a file. 589 # 590 # Deprecated: It is neither supported nor functional. 591 592 attr_accessor :autorequire # :nodoc: 593 594 ## 595 # Sets the default executable for this gem. 596 # 597 # Deprecated: You must now specify the executable name to Gem.bin_path. 598 599 attr_writer :default_executable 600 601 ## 602 # Path this gemspec was loaded from. This attribute is not persisted. 603 604 attr_reader :loaded_from 605 606 ## 607 # Allows deinstallation of gems with legacy platforms. 608 609 attr_writer :original_platform # :nodoc: 610 611 ## 612 # The version of ruby required by this gem 613 614 attr_reader :required_ruby_version 615 616 ## 617 # The RubyGems version required by this gem 618 619 attr_reader :required_rubygems_version 620 621 ## 622 # The rubyforge project this gem lives under. i.e. RubyGems' 623 # rubyforge_project is "rubygems". 624 # 625 # This option is deprecated. 626 627 attr_accessor :rubyforge_project 628 629 ## 630 # The Gem::Specification version of this gemspec. 631 # 632 # Do not set this, it is set automatically when the gem is packaged. 633 634 attr_accessor :specification_version 635 636 class << self 637 def default_specifications_dir 638 File.join(Gem.default_dir, "specifications", "default") 639 end 640 641 def each_spec(search_dirs) # :nodoc: 642 search_dirs.each { |dir| 643 Dir[File.join(dir, "*.gemspec")].each { |path| 644 spec = Gem::Specification.load path.untaint 645 # #load returns nil if the spec is bad, so we just ignore 646 # it at this stage 647 yield(spec) if spec 648 } 649 } 650 end 651 652 def each_default(&block) # :nodoc: 653 each_spec([default_specifications_dir], 654 &block) 655 end 656 657 def each_normal(&block) # :nodoc: 658 each_spec(dirs, &block) 659 end 660 end 661 662 def self._all # :nodoc: 663 unless defined?(@@all) && @@all then 664 665 specs = {} 666 each_default do |spec| 667 specs[spec.full_name] ||= spec 668 end 669 each_normal do |spec| 670 specs[spec.full_name] ||= spec 671 end 672 673 @@all = specs.values 674 675 # After a reset, make sure already loaded specs 676 # are still marked as activated. 677 specs = {} 678 Gem.loaded_specs.each_value{|s| specs[s] = true} 679 @@all.each{|s| s.activated = true if specs[s]} 680 681 _resort! 682 end 683 @@all 684 end 685 686 def self._resort! # :nodoc: 687 @@all.sort! { |a, b| 688 names = a.name <=> b.name 689 next names if names.nonzero? 690 b.version <=> a.version 691 } 692 end 693 694 ## 695 # Loads the default specifications. It should be called only once. 696 697 def self.load_defaults 698 each_default do |spec| 699 Gem.register_default_spec(spec) 700 end 701 end 702 703 ## 704 # Adds +spec+ to the known specifications, keeping the collection 705 # properly sorted. 706 707 def self.add_spec spec 708 # TODO: find all extraneous adds 709 # puts 710 # p :add_spec => [spec.full_name, caller.reject { |s| s =~ /minitest/ }] 711 712 # TODO: flush the rest of the crap from the tests 713 # raise "no dupes #{spec.full_name} in #{all_names.inspect}" if 714 # _all.include? spec 715 716 raise "nil spec!" unless spec # TODO: remove once we're happy with tests 717 718 return if _all.include? spec 719 720 _all << spec 721 _resort! 722 end 723 724 ## 725 # Adds multiple specs to the known specifications. 726 727 def self.add_specs *specs 728 raise "nil spec!" if specs.any?(&:nil?) # TODO: remove once we're happy 729 730 # TODO: this is much more efficient, but we need the extra checks for now 731 # _all.concat specs 732 # _resort! 733 734 specs.each do |spec| # TODO: slow 735 add_spec spec 736 end 737 end 738 739 ## 740 # Returns all specifications. This method is discouraged from use. 741 # You probably want to use one of the Enumerable methods instead. 742 743 def self.all 744 warn "NOTE: Specification.all called from #{caller.first}" unless 745 Gem::Deprecate.skip 746 _all 747 end 748 749 ## 750 # Sets the known specs to +specs+. Not guaranteed to work for you in 751 # the future. Use at your own risk. Caveat emptor. Doomy doom doom. 752 # Etc etc. 753 # 754 #-- 755 # Makes +specs+ the known specs 756 # Listen, time is a river 757 # Winter comes, code breaks 758 # 759 # -- wilsonb 760 761 def self.all= specs 762 @@all = specs 763 end 764 765 ## 766 # Return full names of all specs in sorted order. 767 768 def self.all_names 769 self._all.map(&:full_name) 770 end 771 772 ## 773 # Return the list of all array-oriented instance variables. 774 #-- 775 # Not sure why we need to use so much stupid reflection in here... 776 777 def self.array_attributes 778 @@array_attributes.dup 779 end 780 781 ## 782 # Return the list of all instance variables. 783 #-- 784 # Not sure why we need to use so much stupid reflection in here... 785 786 def self.attribute_names 787 @@attributes.dup 788 end 789 790 ## 791 # Return the directories that Specification uses to find specs. 792 793 def self.dirs 794 @@dirs ||= Gem.path.collect { |dir| 795 File.join dir.dup.untaint, "specifications" 796 } 797 end 798 799 ## 800 # Set the directories that Specification uses to find specs. Setting 801 # this resets the list of known specs. 802 803 def self.dirs= dirs 804 # TODO: find extra calls to dir= 805 # warn "NOTE: dirs= called from #{caller.first} for #{dirs.inspect}" 806 807 self.reset 808 809 # ugh 810 @@dirs = Array(dirs).map { |dir| File.join dir, "specifications" } 811 end 812 813 extend Enumerable 814 815 ## 816 # Enumerate every known spec. See ::dirs= and ::add_spec to set the list of 817 # specs. 818 819 def self.each 820 return enum_for(:each) unless block_given? 821 822 self._all.each do |x| 823 yield x 824 end 825 end 826 827 ## 828 # Returns every spec that matches +name+ and optional +requirements+. 829 830 def self.find_all_by_name name, *requirements 831 requirements = Gem::Requirement.default if requirements.empty? 832 833 # TODO: maybe try: find_all { |s| spec === dep } 834 835 Gem::Dependency.new(name, *requirements).matching_specs 836 end 837 838 ## 839 # Find the best specification matching a +name+ and +requirements+. Raises 840 # if the dependency doesn't resolve to a valid specification. 841 842 def self.find_by_name name, *requirements 843 requirements = Gem::Requirement.default if requirements.empty? 844 845 # TODO: maybe try: find { |s| spec === dep } 846 847 Gem::Dependency.new(name, *requirements).to_spec 848 end 849 850 ## 851 # Return the best specification that contains the file matching +path+. 852 853 def self.find_by_path path 854 self.find { |spec| 855 spec.contains_requirable_file? path 856 } 857 end 858 859 ## 860 # Return the best specification that contains the file matching +path+ 861 # amongst the specs that are not activated. 862 863 def self.find_inactive_by_path path 864 self.find { |spec| 865 spec.contains_requirable_file? path unless spec.activated? 866 } 867 end 868 869 ## 870 # Return currently unresolved specs that contain the file matching +path+. 871 872 def self.find_in_unresolved path 873 # TODO: do we need these?? Kill it 874 specs = unresolved_deps.values.map { |dep| dep.to_specs }.flatten 875 876 specs.find_all { |spec| spec.contains_requirable_file? path } 877 end 878 879 ## 880 # Search through all unresolved deps and sub-dependencies and return 881 # specs that contain the file matching +path+. 882 883 def self.find_in_unresolved_tree path 884 specs = unresolved_deps.values.map { |dep| dep.to_specs }.flatten 885 886 specs.reverse_each do |spec| 887 trails = [] 888 spec.traverse do |from_spec, dep, to_spec, trail| 889 next unless to_spec.conflicts.empty? 890 trails << trail if to_spec.contains_requirable_file? path 891 end 892 893 next if trails.empty? 894 895 return trails.map(&:reverse).sort.first.reverse 896 end 897 898 [] 899 end 900 901 ## 902 # Special loader for YAML files. When a Specification object is loaded 903 # from a YAML file, it bypasses the normal Ruby object initialization 904 # routine (#initialize). This method makes up for that and deals with 905 # gems of different ages. 906 # 907 # +input+ can be anything that YAML.load() accepts: String or IO. 908 909 def self.from_yaml(input) 910 Gem.load_yaml 911 912 input = normalize_yaml_input input 913 spec = YAML.load input 914 915 if spec && spec.class == FalseClass then 916 raise Gem::EndOfYAMLException 917 end 918 919 unless Gem::Specification === spec then 920 raise Gem::Exception, "YAML data doesn't evaluate to gem specification" 921 end 922 923 spec.specification_version ||= NONEXISTENT_SPECIFICATION_VERSION 924 spec.reset_nil_attributes_to_default 925 926 spec 927 end 928 929 ## 930 # Return the latest specs, optionally including prerelease specs if 931 # +prerelease+ is true. 932 933 def self.latest_specs prerelease = false 934 result = Hash.new { |h,k| h[k] = {} } 935 native = {} 936 937 Gem::Specification.reverse_each do |spec| 938 next if spec.version.prerelease? unless prerelease 939 940 native[spec.name] = spec.version if spec.platform == Gem::Platform::RUBY 941 result[spec.name][spec.platform] = spec 942 end 943 944 result.map(&:last).map(&:values).flatten.reject { |spec| 945 minimum = native[spec.name] 946 minimum && spec.version < minimum 947 } 948 end 949 950 ## 951 # Loads Ruby format gemspec from +file+. 952 953 def self.load file 954 return unless file 955 file = file.dup.untaint 956 return unless File.file?(file) 957 958 code = if defined? Encoding 959 File.read file, :mode => 'r:UTF-8:-' 960 else 961 File.read file 962 end 963 964 code.untaint 965 966 begin 967 spec = eval code, binding, file 968 969 if Gem::Specification === spec 970 spec.loaded_from = file.to_s 971 return spec 972 end 973 974 warn "[#{file}] isn't a Gem::Specification (#{spec.class} instead)." 975 rescue SignalException, SystemExit 976 raise 977 rescue SyntaxError, Exception => e 978 warn "Invalid gemspec in [#{file}]: #{e}" 979 end 980 981 nil 982 end 983 984 ## 985 # Specification attributes that must be non-nil 986 987 def self.non_nil_attributes 988 @@non_nil_attributes.dup 989 end 990 991 ## 992 # Make sure the YAML specification is properly formatted with dashes 993 994 def self.normalize_yaml_input(input) 995 result = input.respond_to?(:read) ? input.read : input 996 result = "--- " + result unless result =~ /\A--- / 997 result.gsub!(/ !!null \n/, " \n") 998 # date: 2011-04-26 00:00:00.000000000Z 999 # date: 2011-04-26 00:00:00.000000000 Z 1000 result.gsub!(/^(date: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+?)Z/, '\1 Z') 1001 result 1002 end 1003 1004 ## 1005 # Return a list of all outdated specifications. This method is HEAVY 1006 # as it must go fetch specifications from the server. 1007 1008 def self.outdated 1009 outdateds = [] 1010 1011 # TODO: maybe we should switch to rubygems' version service? 1012 fetcher = Gem::SpecFetcher.fetcher 1013 1014 latest_specs(true).each do |local| 1015 dependency = Gem::Dependency.new local.name, ">= #{local.version}" 1016 remotes, _ = fetcher.search_for_dependency dependency 1017 remotes = remotes.map { |n, _| n.version } 1018 latest = remotes.sort.last 1019 1020 outdateds << local.name if latest and local.version < latest 1021 end 1022 1023 outdateds 1024 end 1025 1026 ## 1027 # Removes +spec+ from the known specs. 1028 1029 def self.remove_spec spec 1030 _all.delete spec 1031 end 1032 1033 ## 1034 # Is +name+ a required attribute? 1035 1036 def self.required_attribute?(name) 1037 @@required_attributes.include? name.to_sym 1038 end 1039 1040 ## 1041 # Required specification attributes 1042 1043 def self.required_attributes 1044 @@required_attributes.dup 1045 end 1046 1047 ## 1048 # Reset the list of known specs, running pre and post reset hooks 1049 # registered in Gem. 1050 1051 def self.reset 1052 @@dirs = nil 1053 Gem.pre_reset_hooks.each { |hook| hook.call } 1054 @@all = nil 1055 unresolved = unresolved_deps 1056 unless unresolved.empty? then 1057 w = "W" + "ARN" 1058 warn "#{w}: Unresolved specs during Gem::Specification.reset:" 1059 unresolved.values.each do |dep| 1060 warn " #{dep}" 1061 end 1062 warn "#{w}: Clearing out unresolved specs." 1063 warn "Please report a bug if this causes problems." 1064 unresolved.clear 1065 end 1066 Gem.post_reset_hooks.each { |hook| hook.call } 1067 end 1068 1069 # DOC: This method needs documented or nodoc'd 1070 def self.unresolved_deps 1071 @unresolved_deps ||= Hash.new { |h, n| h[n] = Gem::Dependency.new n } 1072 end 1073 1074 ## 1075 # Load custom marshal format, re-initializing defaults as needed 1076 1077 def self._load(str) 1078 array = Marshal.load str 1079 1080 spec = Gem::Specification.new 1081 spec.instance_variable_set :@specification_version, array[1] 1082 1083 current_version = CURRENT_SPECIFICATION_VERSION 1084 1085 field_count = if spec.specification_version > current_version then 1086 spec.instance_variable_set :@specification_version, 1087 current_version 1088 MARSHAL_FIELDS[current_version] 1089 else 1090 MARSHAL_FIELDS[spec.specification_version] 1091 end 1092 1093 if array.size < field_count then 1094 raise TypeError, "invalid Gem::Specification format #{array.inspect}" 1095 end 1096 1097 # Cleanup any YAML::PrivateType. They only show up for an old bug 1098 # where nil => null, so just convert them to nil based on the type. 1099 1100 array.map! { |e| e.kind_of?(YAML::PrivateType) ? nil : e } 1101 1102 spec.instance_variable_set :@rubygems_version, array[0] 1103 # spec version 1104 spec.instance_variable_set :@name, array[2] 1105 spec.instance_variable_set :@version, array[3] 1106 spec.date = array[4] 1107 spec.instance_variable_set :@summary, array[5] 1108 spec.instance_variable_set :@required_ruby_version, array[6] 1109 spec.instance_variable_set :@required_rubygems_version, array[7] 1110 spec.instance_variable_set :@original_platform, array[8] 1111 spec.instance_variable_set :@dependencies, array[9] 1112 spec.instance_variable_set :@rubyforge_project, array[10] 1113 spec.instance_variable_set :@email, array[11] 1114 spec.instance_variable_set :@authors, array[12] 1115 spec.instance_variable_set :@description, array[13] 1116 spec.instance_variable_set :@homepage, array[14] 1117 spec.instance_variable_set :@has_rdoc, array[15] 1118 spec.instance_variable_set :@new_platform, array[16] 1119 spec.instance_variable_set :@platform, array[16].to_s 1120 spec.instance_variable_set :@license, array[17] 1121 spec.instance_variable_set :@metadata, array[18] 1122 spec.instance_variable_set :@loaded, false 1123 spec.instance_variable_set :@activated, false 1124 1125 spec 1126 end 1127 1128 def <=>(other) # :nodoc: 1129 sort_obj <=> other.sort_obj 1130 end 1131 1132 def == other # :nodoc: 1133 self.class === other && 1134 name == other.name && 1135 version == other.version && 1136 platform == other.platform 1137 end 1138 1139 ## 1140 # Dump only crucial instance variables. 1141 #-- 1142 # MAINTAIN ORDER! 1143 # (down with the man) 1144 1145 def _dump(limit) 1146 Marshal.dump [ 1147 @rubygems_version, 1148 @specification_version, 1149 @name, 1150 @version, 1151 date, 1152 @summary, 1153 @required_ruby_version, 1154 @required_rubygems_version, 1155 @original_platform, 1156 @dependencies, 1157 @rubyforge_project, 1158 @email, 1159 @authors, 1160 @description, 1161 @homepage, 1162 true, # has_rdoc 1163 @new_platform, 1164 @licenses, 1165 @metadata 1166 ] 1167 end 1168 1169 ## 1170 # Activate this spec, registering it as a loaded spec and adding 1171 # it's lib paths to $LOAD_PATH. Returns true if the spec was 1172 # activated, false if it was previously activated. Freaks out if 1173 # there are conflicts upon activation. 1174 1175 def activate 1176 raise_if_conflicts 1177 1178 return false if Gem.loaded_specs[self.name] 1179 1180 activate_dependencies 1181 add_self_to_load_path 1182 1183 Gem.loaded_specs[self.name] = self 1184 @activated = true 1185 @loaded = true 1186 1187 return true 1188 end 1189 1190 ## 1191 # Activate all unambiguously resolved runtime dependencies of this 1192 # spec. Add any ambigous dependencies to the unresolved list to be 1193 # resolved later, as needed. 1194 1195 def activate_dependencies 1196 unresolved = Gem::Specification.unresolved_deps 1197 1198 self.runtime_dependencies.each do |spec_dep| 1199 if loaded = Gem.loaded_specs[spec_dep.name] 1200 next if spec_dep.matches_spec? loaded 1201 1202 msg = "can't satisfy '#{spec_dep}', already activated '#{loaded.full_name}'" 1203 e = Gem::LoadError.new msg 1204 e.name = spec_dep.name 1205 1206 raise e 1207 end 1208 1209 specs = spec_dep.to_specs 1210 1211 if specs.size == 1 then 1212 specs.first.activate 1213 else 1214 name = spec_dep.name 1215 unresolved[name] = unresolved[name].merge spec_dep 1216 end 1217 end 1218 1219 unresolved.delete self.name 1220 end 1221 1222 ## 1223 # Returns an array with bindir attached to each executable in the 1224 # +executables+ list 1225 1226 def add_bindir(executables) 1227 return nil if executables.nil? 1228 1229 if @bindir then 1230 Array(executables).map { |e| File.join(@bindir, e) } 1231 else 1232 executables 1233 end 1234 rescue 1235 return nil 1236 end 1237 1238 ## 1239 # Adds a dependency on gem +dependency+ with type +type+ that requires 1240 # +requirements+. Valid types are currently <tt>:runtime</tt> and 1241 # <tt>:development</tt>. 1242 1243 def add_dependency_with_type(dependency, type, *requirements) 1244 requirements = if requirements.empty? then 1245 Gem::Requirement.default 1246 else 1247 requirements.flatten 1248 end 1249 1250 unless dependency.respond_to?(:name) && 1251 dependency.respond_to?(:version_requirements) 1252 dependency = Gem::Dependency.new(dependency.to_s, requirements, type) 1253 end 1254 1255 dependencies << dependency 1256 end 1257 1258 private :add_dependency_with_type 1259 1260 alias add_dependency add_runtime_dependency 1261 1262 ## 1263 # Adds this spec's require paths to LOAD_PATH, in the proper location. 1264 1265 def add_self_to_load_path 1266 return if default_gem? 1267 1268 paths = require_paths.map do |path| 1269 File.join full_gem_path, path 1270 end 1271 1272 # gem directories must come after -I and ENV['RUBYLIB'] 1273 insert_index = Gem.load_path_insert_index 1274 1275 if insert_index then 1276 # gem directories must come after -I and ENV['RUBYLIB'] 1277 $LOAD_PATH.insert(insert_index, *paths) 1278 else 1279 # we are probably testing in core, -I and RUBYLIB don't apply 1280 $LOAD_PATH.unshift(*paths) 1281 end 1282 end 1283 1284 ## 1285 # Singular reader for #authors. Returns the first author in the list 1286 1287 def author 1288 val = authors and val.first 1289 end 1290 1291 ## 1292 # The list of author names who wrote this gem. 1293 # 1294 # spec.authors = ['Chad Fowler', 'Jim Weirich', 'Rich Kilmer'] 1295 1296 def authors 1297 @authors ||= [] 1298 end 1299 1300 ## 1301 # Returns the full path to the base gem directory. 1302 # 1303 # eg: /usr/local/lib/ruby/gems/1.8 1304 1305 def base_dir 1306 return Gem.dir unless loaded_from 1307 @base_dir ||= if default_gem? then 1308 File.dirname File.dirname File.dirname loaded_from 1309 else 1310 File.dirname File.dirname loaded_from 1311 end 1312 end 1313 1314 ## 1315 # Returns the full path to installed gem's bin directory. 1316 # 1317 # NOTE: do not confuse this with +bindir+, which is just 'bin', not 1318 # a full path. 1319 1320 def bin_dir 1321 @bin_dir ||= File.join gem_dir, bindir # TODO: this is unfortunate 1322 end 1323 1324 ## 1325 # Returns the full path to an executable named +name+ in this gem. 1326 1327 def bin_file name 1328 File.join bin_dir, name 1329 end 1330 1331 ## 1332 # Returns the build_args used to install the gem 1333 1334 def build_args 1335 if File.exists? build_info_file 1336 File.readlines(build_info_file).map { |x| x.strip } 1337 else 1338 [] 1339 end 1340 end 1341 1342 ## 1343 # Returns the full path to the build info directory 1344 1345 def build_info_dir 1346 File.join base_dir, "build_info" 1347 end 1348 1349 ## 1350 # Returns the full path to the file containing the build 1351 # information generated when the gem was installed 1352 1353 def build_info_file 1354 File.join build_info_dir, "#{full_name}.info" 1355 end 1356 1357 ## 1358 # Returns the full path to the cache directory containing this 1359 # spec's cached gem. 1360 1361 def cache_dir 1362 @cache_dir ||= File.join base_dir, "cache" 1363 end 1364 1365 ## 1366 # Returns the full path to the cached gem for this spec. 1367 1368 def cache_file 1369 @cache_file ||= File.join cache_dir, "#{full_name}.gem" 1370 end 1371 1372 ## 1373 # Return any possible conflicts against the currently loaded specs. 1374 1375 def conflicts 1376 conflicts = {} 1377 Gem.loaded_specs.values.each do |spec| 1378 bad = self.runtime_dependencies.find_all { |dep| 1379 spec.name == dep.name and not spec.satisfies_requirement? dep 1380 } 1381 1382 conflicts[spec] = bad unless bad.empty? 1383 end 1384 conflicts 1385 end 1386 1387 ## 1388 # Return true if this spec can require +file+. 1389 1390 def contains_requirable_file? file 1391 root = full_gem_path 1392 suffixes = Gem.suffixes 1393 1394 require_paths.any? do |lib| 1395 base = "#{root}/#{lib}/#{file}" 1396 suffixes.any? { |suf| File.file? "#{base}#{suf}" } 1397 end 1398 end 1399 1400 ## 1401 # The date this gem was created. Lazily defaults to the current UTC date. 1402 # 1403 # There is no need to set this in your gem specification. 1404 1405 def date 1406 @date ||= TODAY 1407 end 1408 1409 DateTimeFormat = /\A 1410 (\d{4})-(\d{2})-(\d{2}) 1411 (\s+ \d{2}:\d{2}:\d{2}\.\d+ \s* (Z | [-+]\d\d:\d\d) )? 1412 \Z/x 1413 1414 ## 1415 # The date this gem was created 1416 # 1417 # DO NOT set this, it is set automatically when the gem is packaged. 1418 1419 def date= date 1420 # We want to end up with a Time object with one-day resolution. 1421 # This is the cleanest, most-readable, faster-than-using-Date 1422 # way to do it. 1423 @date = case date 1424 when String then 1425 if DateTimeFormat =~ date then 1426 Time.utc($1.to_i, $2.to_i, $3.to_i) 1427 1428 # Workaround for where the date format output from psych isn't 1429 # parsed as a Time object by syck and thus comes through as a 1430 # string. 1431 elsif /\A(\d{4})-(\d{2})-(\d{2}) \d{2}:\d{2}:\d{2}\.\d+?Z\z/ =~ date then 1432 Time.utc($1.to_i, $2.to_i, $3.to_i) 1433 else 1434 raise(Gem::InvalidSpecificationException, 1435 "invalid date format in specification: #{date.inspect}") 1436 end 1437 when Time, Date then 1438 Time.utc(date.year, date.month, date.day) 1439 else 1440 TODAY 1441 end 1442 end 1443 1444 ## 1445 # The default executable for this gem. 1446 # 1447 # Deprecated: The name of the gem is assumed to be the name of the 1448 # executable now. See Gem.bin_path. 1449 1450 def default_executable # :nodoc: 1451 if defined?(@default_executable) and @default_executable 1452 result = @default_executable 1453 elsif @executables and @executables.size == 1 1454 result = Array(@executables).first 1455 else 1456 result = nil 1457 end 1458 result 1459 end 1460 1461 ## 1462 # The default value for specification attribute +name+ 1463 1464 def default_value name 1465 @@default_value[name] 1466 end 1467 1468 ## 1469 # A list of Gem::Dependency objects this gem depends on. 1470 # 1471 # Use #add_dependency or #add_development_dependency to add dependencies to 1472 # a gem. 1473 1474 def dependencies 1475 @dependencies ||= [] 1476 end 1477 1478 ## 1479 # Return a list of all gems that have a dependency on this gemspec. The 1480 # list is structured with entries that conform to: 1481 # 1482 # [depending_gem, dependency, [list_of_gems_that_satisfy_dependency]] 1483 1484 def dependent_gems 1485 # REFACTOR: out = []; each; out; ? Really? No #collect love? 1486 out = [] 1487 Gem::Specification.each do |spec| 1488 spec.dependencies.each do |dep| 1489 if self.satisfies_requirement?(dep) then 1490 sats = [] 1491 find_all_satisfiers(dep) do |sat| 1492 sats << sat 1493 end 1494 out << [spec, dep, sats] 1495 end 1496 end 1497 end 1498 out 1499 end 1500 1501 ## 1502 # Returns all specs that matches this spec's runtime dependencies. 1503 1504 def dependent_specs 1505 runtime_dependencies.map { |dep| dep.to_specs }.flatten 1506 end 1507 1508 ## 1509 # A detailed description of this gem. See also #summary 1510 1511 def description= str 1512 @description = str.to_s 1513 end 1514 1515 ## 1516 # List of dependencies that are used for development 1517 1518 def development_dependencies 1519 dependencies.select { |d| d.type == :development } 1520 end 1521 1522 ## 1523 # Returns the full path to this spec's documentation directory. If +type+ 1524 # is given it will be appended to the end. For examlpe: 1525 # 1526 # spec.doc_dir # => "/path/to/gem_repo/doc/a-1" 1527 # 1528 # spec.doc_dir 'ri' # => "/path/to/gem_repo/doc/a-1/ri" 1529 1530 def doc_dir type = nil 1531 @doc_dir ||= File.join base_dir, 'doc', full_name 1532 1533 if type then 1534 File.join @doc_dir, type 1535 else 1536 @doc_dir 1537 end 1538 end 1539 1540 def encode_with coder # :nodoc: 1541 mark_version 1542 1543 coder.add 'name', @name 1544 coder.add 'version', @version 1545 platform = case @original_platform 1546 when nil, '' then 1547 'ruby' 1548 when String then 1549 @original_platform 1550 else 1551 @original_platform.to_s 1552 end 1553 coder.add 'platform', platform 1554 1555 attributes = @@attributes.map(&:to_s) - %w[name version platform] 1556 attributes.each do |name| 1557 coder.add name, instance_variable_get("@#{name}") 1558 end 1559 end 1560 1561 def eql? other # :nodoc: 1562 self.class === other && same_attributes?(other) 1563 end 1564 1565 ## 1566 # Singular accessor for #executables 1567 1568 def executable 1569 val = executables and val.first 1570 end 1571 1572 ## 1573 # Singular accessor for #executables 1574 1575 def executable=o 1576 self.executables = [o] 1577 end 1578 1579 ## 1580 # Sets executables to +value+, ensuring it is an array. Don't 1581 # use this, push onto the array instead. 1582 1583 def executables= value 1584 # TODO: warn about setting instead of pushing 1585 @executables = Array(value) 1586 end 1587 1588 ## 1589 # Sets extensions to +extensions+, ensuring it is an array. Don't 1590 # use this, push onto the array instead. 1591 1592 def extensions= extensions 1593 # TODO: warn about setting instead of pushing 1594 @extensions = Array extensions 1595 end 1596 1597 ## 1598 # Sets extra_rdoc_files to +files+, ensuring it is an array. Don't 1599 # use this, push onto the array instead. 1600 1601 def extra_rdoc_files= files 1602 # TODO: warn about setting instead of pushing 1603 @extra_rdoc_files = Array files 1604 end 1605 1606 ## 1607 # The default (generated) file name of the gem. See also #spec_name. 1608 # 1609 # spec.file_name # => "example-1.0.gem" 1610 1611 def file_name 1612 "#{full_name}.gem" 1613 end 1614 1615 ## 1616 # Sets files to +files+, ensuring it is an array. 1617 1618 def files= files 1619 @files = Array files 1620 end 1621 1622 ## 1623 # Finds all gems that satisfy +dep+ 1624 1625 def find_all_satisfiers dep 1626 Gem::Specification.each do |spec| 1627 yield spec if spec.satisfies_requirement? dep 1628 end 1629 end 1630 1631 private :find_all_satisfiers 1632 1633 ## 1634 # Creates a duplicate spec without large blobs that aren't used at runtime. 1635 1636 def for_cache 1637 spec = dup 1638 1639 spec.files = nil 1640 spec.test_files = nil 1641 1642 spec 1643 end 1644 1645 ## 1646 # The full path to the gem (install path + full name). 1647 1648 def full_gem_path 1649 # TODO: This is a heavily used method by gems, so we'll need 1650 # to aleast just alias it to #gem_dir rather than remove it. 1651 1652 # TODO: also, shouldn't it default to full_name if it hasn't been written? 1653 return @full_gem_path if defined?(@full_gem_path) && @full_gem_path 1654 1655 @full_gem_path = File.expand_path File.join(gems_dir, full_name) 1656 @full_gem_path.untaint 1657 1658 return @full_gem_path if File.directory? @full_gem_path 1659 1660 @full_gem_path = File.expand_path File.join(gems_dir, original_name) 1661 end 1662 1663 ## 1664 # Returns the full name (name-version) of this Gem. Platform information 1665 # is included (name-version-platform) if it is specified and not the 1666 # default Ruby platform. 1667 1668 def full_name 1669 @full_name ||= if platform == Gem::Platform::RUBY or platform.nil? then 1670 "#{@name}-#{@version}".untaint 1671 else 1672 "#{@name}-#{@version}-#{platform}".untaint 1673 end 1674 end 1675 1676 ## 1677 # Returns the full path to this spec's gem directory. 1678 # eg: /usr/local/lib/ruby/1.8/gems/mygem-1.0 1679 1680 def gem_dir 1681 @gem_dir ||= File.expand_path File.join(gems_dir, full_name) 1682 end 1683 1684 ## 1685 # Returns the full path to the gems directory containing this spec's 1686 # gem directory. eg: /usr/local/lib/ruby/1.8/gems 1687 1688 def gems_dir 1689 # TODO: this logic seems terribly broken, but tests fail if just base_dir 1690 @gems_dir ||= File.join(loaded_from && base_dir || Gem.dir, "gems") 1691 end 1692 1693 ## 1694 # Deprecated and ignored, defaults to true. 1695 # 1696 # Formerly used to indicate this gem was RDoc-capable. 1697 1698 def has_rdoc # :nodoc: 1699 true 1700 end 1701 1702 ## 1703 # Deprecated and ignored. 1704 # 1705 # Formerly used to indicate this gem was RDoc-capable. 1706 1707 def has_rdoc= ignored # :nodoc: 1708 @has_rdoc = true 1709 end 1710 1711 alias :has_rdoc? :has_rdoc # :nodoc: 1712 1713 ## 1714 # True if this gem has files in test_files 1715 1716 def has_unit_tests? 1717 not test_files.empty? 1718 end 1719 1720 # :stopdoc: 1721 alias has_test_suite? has_unit_tests? 1722 # :startdoc: 1723 1724 def hash # :nodoc: 1725 @@attributes.inject(0) { |hash_code, (name, _)| 1726 hash_code ^ self.send(name).hash 1727 } 1728 end 1729 1730 def init_with coder # :nodoc: 1731 yaml_initialize coder.tag, coder.map 1732 end 1733 1734 ## 1735 # Specification constructor. Assigns the default values to the attributes 1736 # and yields itself for further initialization. Optionally takes +name+ and 1737 # +version+. 1738 1739 def initialize name = nil, version = nil 1740 @loaded = false 1741 @activated = false 1742 @loaded_from = nil 1743 @original_platform = nil 1744 1745 @@nil_attributes.each do |key| 1746 instance_variable_set "@#{key}", nil 1747 end 1748 1749 @@non_nil_attributes.each do |key| 1750 default = default_value(key) 1751 value = case default 1752 when Time, Numeric, Symbol, true, false, nil then default 1753 else default.dup 1754 end 1755 1756 instance_variable_set "@#{key}", value 1757 end 1758 1759 @new_platform = Gem::Platform::RUBY 1760 1761 self.name = name if name 1762 self.version = version if version 1763 1764 yield self if block_given? 1765 end 1766 1767 ## 1768 # Duplicates array_attributes from +other_spec+ so state isn't shared. 1769 1770 def initialize_copy other_spec 1771 self.class.array_attributes.each do |name| 1772 name = :"@#{name}" 1773 next unless other_spec.instance_variable_defined? name 1774 1775 begin 1776 val = other_spec.instance_variable_get(name) 1777 if val then 1778 instance_variable_set name, val.dup 1779 elsif Gem.configuration.really_verbose 1780 warn "WARNING: #{full_name} has an invalid nil value for #{name}" 1781 end 1782 rescue TypeError 1783 e = Gem::FormatException.new \ 1784 "#{full_name} has an invalid value for #{name}" 1785 1786 e.file_path = loaded_from 1787 raise e 1788 end 1789 end 1790 end 1791 1792 ## 1793 # Expire memoized instance variables that can incorrectly generate, replace 1794 # or miss files due changes in certain attributes used to compute them. 1795 1796 def invalidate_memoized_attributes 1797 @full_name = nil 1798 @cache_file = nil 1799 end 1800 1801 private :invalidate_memoized_attributes 1802 1803 def inspect 1804 if $DEBUG 1805 super 1806 else 1807 "#<#{self.class}:0x#{__id__.to_s(16)} #{full_name}>" 1808 end 1809 end 1810 1811 ## 1812 # Returns a string usable in Dir.glob to match all requirable paths 1813 # for this spec. 1814 1815 def lib_dirs_glob 1816 dirs = if self.require_paths.size > 1 then 1817 "{#{self.require_paths.join(',')}}" 1818 else 1819 self.require_paths.first 1820 end 1821 1822 "#{self.full_gem_path}/#{dirs}" 1823 end 1824 1825 ## 1826 # Files in the Gem under one of the require_paths 1827 1828 def lib_files 1829 @files.select do |file| 1830 require_paths.any? do |path| 1831 file.start_with? path 1832 end 1833 end 1834 end 1835 1836 ## 1837 # Singular accessor for #licenses 1838 1839 def license 1840 val = licenses and val.first 1841 end 1842 1843 ## 1844 # Plural accessor for setting licenses 1845 1846 def licenses 1847 @licenses ||= [] 1848 end 1849 1850 ## 1851 # Set the location a Specification was loaded from. +obj+ is converted 1852 # to a String. 1853 1854 def loaded_from= path 1855 @loaded_from = path.to_s 1856 1857 # reset everything @loaded_from depends upon 1858 @base_dir = nil 1859 @bin_dir = nil 1860 @cache_dir = nil 1861 @cache_file = nil 1862 @doc_dir = nil 1863 @full_gem_path = nil 1864 @gem_dir = nil 1865 @gems_dir = nil 1866 @ri_dir = nil 1867 @spec_dir = nil 1868 @spec_file = nil 1869 end 1870 1871 ## 1872 # Sets the rubygems_version to the current RubyGems version. 1873 1874 def mark_version 1875 @rubygems_version = Gem::VERSION 1876 end 1877 1878 ## 1879 # Return all files in this gem that match for +glob+. 1880 1881 def matches_for_glob glob # TODO: rename? 1882 # TODO: do we need these?? Kill it 1883 glob = File.join(self.lib_dirs_glob, glob) 1884 1885 Dir[glob].map { |f| f.untaint } # FIX our tests are broken, run w/ SAFE=1 1886 end 1887 1888 ## 1889 # Warn about unknown attributes while loading a spec. 1890 1891 def method_missing(sym, *a, &b) # :nodoc: 1892 if @specification_version > CURRENT_SPECIFICATION_VERSION and 1893 sym.to_s =~ /=$/ then 1894 warn "ignoring #{sym} loading #{full_name}" if $DEBUG 1895 else 1896 super 1897 end 1898 end 1899 1900 ## 1901 # Normalize the list of files so that: 1902 # * All file lists have redundancies removed. 1903 # * Files referenced in the extra_rdoc_files are included in the package 1904 # file list. 1905 1906 def normalize 1907 if defined?(@extra_rdoc_files) and @extra_rdoc_files then 1908 @extra_rdoc_files.uniq! 1909 @files ||= [] 1910 @files.concat(@extra_rdoc_files) 1911 end 1912 1913 @files = @files.uniq if @files 1914 @extensions = @extensions.uniq if @extensions 1915 @test_files = @test_files.uniq if @test_files 1916 @executables = @executables.uniq if @executables 1917 @extra_rdoc_files = @extra_rdoc_files.uniq if @extra_rdoc_files 1918 end 1919 1920 ## 1921 # Return a NameTuple that represents this Specification 1922 1923 def name_tuple 1924 Gem::NameTuple.new name, version, original_platform 1925 end 1926 1927 ## 1928 # Returns the full name (name-version) of this gemspec using the original 1929 # platform. For use with legacy gems. 1930 1931 def original_name # :nodoc: 1932 if platform == Gem::Platform::RUBY or platform.nil? then 1933 "#{@name}-#{@version}" 1934 else 1935 "#{@name}-#{@version}-#{@original_platform}" 1936 end 1937 end 1938 1939 ## 1940 # Cruft. Use +platform+. 1941 1942 def original_platform # :nodoc: 1943 @original_platform ||= platform 1944 end 1945 1946 ## 1947 # The platform this gem runs on. See Gem::Platform for details. 1948 1949 def platform 1950 @new_platform ||= Gem::Platform::RUBY 1951 end 1952 1953 def pretty_print(q) # :nodoc: 1954 q.group 2, 'Gem::Specification.new do |s|', 'end' do 1955 q.breakable 1956 1957 # REFACTOR: each_attr - use in to_yaml as well 1958 @@attributes.each do |attr_name| 1959 current_value = self.send attr_name 1960 if current_value != default_value(attr_name) or 1961 self.class.required_attribute? attr_name then 1962 1963 q.text "s.#{attr_name} = " 1964 1965 if attr_name == :date then 1966 current_value = current_value.utc 1967 1968 q.text "Time.utc(#{current_value.year}, #{current_value.month}, #{current_value.day})" 1969 else 1970 q.pp current_value 1971 end 1972 1973 q.breakable 1974 end 1975 end 1976 end 1977 end 1978 1979 ## 1980 # Check the spec for possible conflicts and freak out if there are any. 1981 1982 def raise_if_conflicts 1983 other = Gem.loaded_specs[self.name] 1984 1985 if other and self.version != other.version then 1986 # This gem is already loaded. If the currently loaded gem is not in the 1987 # list of candidate gems, then we have a version conflict. 1988 1989 msg = "can't activate #{full_name}, already activated #{other.full_name}" 1990 1991 e = Gem::LoadError.new msg 1992 e.name = self.name 1993 # TODO: e.requirement = dep.requirement 1994 1995 raise e 1996 end 1997 1998 conf = self.conflicts 1999 2000 unless conf.empty? then 2001 y = conf.map { |act,con| 2002 "#{act.full_name} conflicts with #{con.join(", ")}" 2003 }.join ", " 2004 2005 # TODO: improve message by saying who activated `con` 2006 2007 raise Gem::LoadError, "Unable to activate #{self.full_name}, because #{y}" 2008 end 2009 end 2010 2011 ## 2012 # Sets rdoc_options to +value+, ensuring it is an array. Don't 2013 # use this, push onto the array instead. 2014 2015 def rdoc_options= options 2016 # TODO: warn about setting instead of pushing 2017 @rdoc_options = Array options 2018 end 2019 2020 ## 2021 # Singular accessor for #require_paths 2022 2023 def require_path 2024 val = require_paths and val.first 2025 end 2026 2027 ## 2028 # Singular accessor for #require_paths 2029 2030 def require_path= path 2031 self.require_paths = [path] 2032 end 2033 2034 ## 2035 # The RubyGems version required by this gem 2036 2037 def required_rubygems_version= req 2038 @required_rubygems_version = Gem::Requirement.create req 2039 end 2040 2041 ## 2042 # Set requirements to +req+, ensuring it is an array. Don't 2043 # use this, push onto the array instead. 2044 2045 def requirements= req 2046 # TODO: warn about setting instead of pushing 2047 @requirements = Array req 2048 end 2049 2050 ## 2051 # Returns the full path to this spec's ri directory. 2052 2053 def ri_dir 2054 @ri_dir ||= File.join base_dir, 'ri', full_name 2055 end 2056 2057 ## 2058 # Return a string containing a Ruby code representation of the given 2059 # object. 2060 2061 def ruby_code(obj) 2062 case obj 2063 when String then obj.dump 2064 when Array then '[' + obj.map { |x| ruby_code x }.join(", ") + ']' 2065 when Hash then 2066 seg = obj.keys.sort.map { |k| "#{k.to_s.dump} => #{obj[k].to_s.dump}" } 2067 "{ #{seg.join(', ')} }" 2068 when Gem::Version then obj.to_s.dump 2069 when Date then obj.strftime('%Y-%m-%d').dump 2070 when Time then obj.strftime('%Y-%m-%d').dump 2071 when Numeric then obj.inspect 2072 when true, false, nil then obj.inspect 2073 when Gem::Platform then "Gem::Platform.new(#{obj.to_a.inspect})" 2074 when Gem::Requirement then 2075 list = obj.as_list 2076 "Gem::Requirement.new(#{ruby_code(list.size == 1 ? obj.to_s : list)})" 2077 else raise Gem::Exception, "ruby_code case not handled: #{obj.class}" 2078 end 2079 end 2080 2081 private :ruby_code 2082 2083 ## 2084 # List of dependencies that will automatically be activated at runtime. 2085 2086 def runtime_dependencies 2087 dependencies.select { |d| d.type == :runtime } 2088 end 2089 2090 ## 2091 # True if this gem has the same attributes as +other+. 2092 2093 def same_attributes? spec 2094 @@attributes.all? { |name, default| self.send(name) == spec.send(name) } 2095 end 2096 2097 private :same_attributes? 2098 2099 ## 2100 # Checks if this specification meets the requirement of +dependency+. 2101 2102 def satisfies_requirement? dependency 2103 return @name == dependency.name && 2104 dependency.requirement.satisfied_by?(@version) 2105 end 2106 2107 ## 2108 # Returns an object you can use to sort specifications in #sort_by. 2109 2110 def sort_obj 2111 # TODO: this is horrible. Deprecate it. 2112 [@name, @version, @new_platform == Gem::Platform::RUBY ? -1 : 1] 2113 end 2114 2115 ## 2116 # Returns the full path to the directory containing this spec's 2117 # gemspec file. eg: /usr/local/lib/ruby/gems/1.8/specifications 2118 2119 def spec_dir 2120 @spec_dir ||= File.join base_dir, "specifications" 2121 end 2122 2123 ## 2124 # Returns the full path to this spec's gemspec file. 2125 # eg: /usr/local/lib/ruby/gems/1.8/specifications/mygem-1.0.gemspec 2126 2127 def spec_file 2128 @spec_file ||= File.join spec_dir, "#{full_name}.gemspec" 2129 end 2130 2131 ## 2132 # The default name of the gemspec. See also #file_name 2133 # 2134 # spec.spec_name # => "example-1.0.gemspec" 2135 2136 def spec_name 2137 "#{full_name}.gemspec" 2138 end 2139 2140 ## 2141 # A short summary of this gem's description. 2142 2143 def summary= str 2144 @summary = str.to_s.strip. 2145 gsub(/(\w-)\n[ \t]*(\w)/, '\1\2').gsub(/\n[ \t]*/, " ") # so. weird. 2146 end 2147 2148 ## 2149 # Singular accessor for #test_files 2150 2151 def test_file 2152 val = test_files and val.first 2153 end 2154 2155 ## 2156 # Singular mutator for #test_files 2157 2158 def test_file= file 2159 self.test_files = [file] 2160 end 2161 2162 ## 2163 # Test files included in this gem. You cannot append to this accessor, you 2164 # must assign to it. 2165 2166 def test_files 2167 # Handle the possibility that we have @test_suite_file but not 2168 # @test_files. This will happen when an old gem is loaded via 2169 # YAML. 2170 if defined? @test_suite_file then 2171 @test_files = [@test_suite_file].flatten 2172 @test_suite_file = nil 2173 end 2174 if defined?(@test_files) and @test_files then 2175 @test_files 2176 else 2177 @test_files = [] 2178 end 2179 end 2180 2181 ## 2182 # Returns a Ruby code representation of this specification, such that it can 2183 # be eval'ed and reconstruct the same specification later. Attributes that 2184 # still have their default values are omitted. 2185 # 2186 # REFACTOR: This, plus stuff like #ruby_code and #pretty_print, should 2187 # probably be extracted out into some sort of separate class. SRP, do you 2188 # speak it!??! 2189 2190 def to_ruby 2191 mark_version 2192 result = [] 2193 result << "# -*- encoding: utf-8 -*-" 2194 result << nil 2195 result << "Gem::Specification.new do |s|" 2196 2197 result << " s.name = #{ruby_code name}" 2198 result << " s.version = #{ruby_code version}" 2199 unless platform.nil? or platform == Gem::Platform::RUBY then 2200 result << " s.platform = #{ruby_code original_platform}" 2201 end 2202 result << "" 2203 result << " s.required_rubygems_version = #{ruby_code required_rubygems_version} if s.respond_to? :required_rubygems_version=" 2204 2205 if metadata and !metadata.empty? 2206 result << " s.metadata = #{ruby_code metadata} if s.respond_to? :metadata=" 2207 end 2208 2209 handled = [ 2210 :dependencies, 2211 :name, 2212 :platform, 2213 :required_rubygems_version, 2214 :specification_version, 2215 :version, 2216 :has_rdoc, 2217 :default_executable, 2218 :metadata 2219 ] 2220 2221 @@attributes.each do |attr_name| 2222 next if handled.include? attr_name 2223 current_value = self.send(attr_name) 2224 if current_value != default_value(attr_name) or 2225 self.class.required_attribute? attr_name then 2226 result << " s.#{attr_name} = #{ruby_code current_value}" 2227 end 2228 end 2229 2230 unless dependencies.empty? then 2231 result << nil 2232 result << " if s.respond_to? :specification_version then" 2233 result << " s.specification_version = #{specification_version}" 2234 result << nil 2235 2236 result << " if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then" 2237 2238 dependencies.each do |dep| 2239 req = dep.requirements_list.inspect 2240 dep.instance_variable_set :@type, :runtime if dep.type.nil? # HACK 2241 result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>, #{req})" 2242 end 2243 2244 result << " else" 2245 2246 dependencies.each do |dep| 2247 version_reqs_param = dep.requirements_list.inspect 2248 result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})" 2249 end 2250 2251 result << ' end' 2252 2253 result << " else" 2254 dependencies.each do |dep| 2255 version_reqs_param = dep.requirements_list.inspect 2256 result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})" 2257 end 2258 result << " end" 2259 end 2260 2261 result << "end" 2262 result << nil 2263 2264 result.join "\n" 2265 end 2266 2267 ## 2268 # Returns a Ruby lighter-weight code representation of this specification, 2269 # used for indexing only. 2270 # 2271 # See #to_ruby. 2272 2273 def to_ruby_for_cache 2274 for_cache.to_ruby 2275 end 2276 2277 def to_s # :nodoc: 2278 "#<Gem::Specification name=#{@name} version=#{@version}>" 2279 end 2280 2281 def to_yaml(opts = {}) # :nodoc: 2282 if YAML.const_defined?(:ENGINE) && !YAML::ENGINE.syck? then 2283 # Because the user can switch the YAML engine behind our 2284 # back, we have to check again here to make sure that our 2285 # psych code was properly loaded, and load it if not. 2286 unless Gem.const_defined?(:NoAliasYAMLTree) 2287 require 'rubygems/psych_tree' 2288 end 2289 2290 builder = Gem::NoAliasYAMLTree.create 2291 builder << self 2292 ast = builder.tree 2293 2294 io = StringIO.new 2295 io.set_encoding Encoding::UTF_8 if Object.const_defined? :Encoding 2296 2297 Psych::Visitors::Emitter.new(io).accept(ast) 2298 2299 io.string.gsub(/ !!null \n/, " \n") 2300 else 2301 YAML.quick_emit object_id, opts do |out| 2302 out.map taguri, to_yaml_style do |map| 2303 encode_with map 2304 end 2305 end 2306 end 2307 end 2308 2309 ## 2310 # Recursively walk dependencies of this spec, executing the +block+ for each 2311 # hop. 2312 2313 def traverse trail = [], &block 2314 trail = trail + [self] 2315 runtime_dependencies.each do |dep| 2316 dep.to_specs.each do |dep_spec| 2317 block[self, dep, dep_spec, trail + [dep_spec]] 2318 dep_spec.traverse(trail, &block) unless 2319 trail.map(&:name).include? dep_spec.name 2320 end 2321 end 2322 end 2323 2324 ## 2325 # Checks that the specification contains all required fields, and does a 2326 # very basic sanity check. 2327 # 2328 # Raises InvalidSpecificationException if the spec does not pass the 2329 # checks.. 2330 2331 def validate packaging = true 2332 require 'rubygems/user_interaction' 2333 extend Gem::UserInteraction 2334 normalize 2335 2336 nil_attributes = self.class.non_nil_attributes.find_all do |name| 2337 instance_variable_get("@#{name}").nil? 2338 end 2339 2340 unless nil_attributes.empty? then 2341 raise Gem::InvalidSpecificationException, 2342 "#{nil_attributes.join ', '} must not be nil" 2343 end 2344 2345 if packaging and rubygems_version != Gem::VERSION then 2346 raise Gem::InvalidSpecificationException, 2347 "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}" 2348 end 2349 2350 @@required_attributes.each do |symbol| 2351 unless self.send symbol then 2352 raise Gem::InvalidSpecificationException, 2353 "missing value for attribute #{symbol}" 2354 end 2355 end 2356 2357 unless String === name then 2358 raise Gem::InvalidSpecificationException, 2359 "invalid value for attribute name: \"#{name.inspect}\"" 2360 end 2361 2362 if require_paths.empty? then 2363 raise Gem::InvalidSpecificationException, 2364 'specification must have at least one require_path' 2365 end 2366 2367 @files.delete_if { |x| File.directory?(x) } 2368 @test_files.delete_if { |x| File.directory?(x) } 2369 @executables.delete_if { |x| File.directory?(File.join(@bindir, x)) } 2370 @extra_rdoc_files.delete_if { |x| File.directory?(x) } 2371 @extensions.delete_if { |x| File.directory?(x) } 2372 2373 non_files = files.reject { |x| File.file?(x) } 2374 2375 unless not packaging or non_files.empty? then 2376 raise Gem::InvalidSpecificationException, 2377 "[\"#{non_files.join "\", \""}\"] are not files" 2378 end 2379 2380 unless specification_version.is_a?(Fixnum) 2381 raise Gem::InvalidSpecificationException, 2382 'specification_version must be a Fixnum (did you mean version?)' 2383 end 2384 2385 case platform 2386 when Gem::Platform, Gem::Platform::RUBY then # ok 2387 else 2388 raise Gem::InvalidSpecificationException, 2389 "invalid platform #{platform.inspect}, see Gem::Platform" 2390 end 2391 2392 self.class.array_attributes.each do |field| 2393 val = self.send field 2394 klass = case field 2395 when :dependencies 2396 Gem::Dependency 2397 else 2398 String 2399 end 2400 2401 unless Array === val and val.all? { |x| x.kind_of?(klass) } then 2402 raise(Gem::InvalidSpecificationException, 2403 "#{field} must be an Array of #{klass}") 2404 end 2405 end 2406 2407 # FIX: uhhhh single element array.each? 2408 [:authors].each do |field| 2409 val = self.send field 2410 raise Gem::InvalidSpecificationException, "#{field} may not be empty" if 2411 val.empty? 2412 end 2413 2414 unless Hash === metadata 2415 raise Gem::InvalidSpecificationException, 2416 'metadata must be a hash' 2417 end 2418 2419 metadata.keys.each do |k| 2420 if !k.kind_of?(String) 2421 raise Gem::InvalidSpecificationException, 2422 'metadata keys must be a String' 2423 end 2424 2425 if k.size > 128 2426 raise Gem::InvalidSpecificationException, 2427 "metadata key too large (#{k.size} > 128)" 2428 end 2429 end 2430 2431 metadata.values.each do |k| 2432 if !k.kind_of?(String) 2433 raise Gem::InvalidSpecificationException, 2434 'metadata values must be a String' 2435 end 2436 2437 if k.size > 1024 2438 raise Gem::InvalidSpecificationException, 2439 "metadata value too large (#{k.size} > 1024)" 2440 end 2441 end 2442 2443 licenses.each { |license| 2444 if license.length > 64 2445 raise Gem::InvalidSpecificationException, 2446 "each license must be 64 characters or less" 2447 end 2448 } 2449 2450 alert_warning 'licenses is empty' if licenses.empty? 2451 2452 validate_permissions 2453 2454 # reject lazy developers: 2455 2456 # FIX: Doesn't this just evaluate to "FIXME" or "TODO"? 2457 lazy = '"FIxxxXME" or "TOxxxDO"'.gsub(/xxx/, '') 2458 2459 unless authors.grep(/FI XME|TO DO/x).empty? then 2460 raise Gem::InvalidSpecificationException, "#{lazy} is not an author" 2461 end 2462 2463 unless Array(email).grep(/FI XME|TO DO/x).empty? then 2464 raise Gem::InvalidSpecificationException, "#{lazy} is not an email" 2465 end 2466 2467 if description =~ /FI XME|TO DO/x then 2468 raise Gem::InvalidSpecificationException, "#{lazy} is not a description" 2469 end 2470 2471 if summary =~ /FI XME|TO DO/x then 2472 raise Gem::InvalidSpecificationException, "#{lazy} is not a summary" 2473 end 2474 2475 if homepage and not homepage.empty? and 2476 homepage !~ /\A[a-z][a-z\d+.-]*:/i then 2477 raise Gem::InvalidSpecificationException, 2478 "\"#{homepage}\" is not a URI" 2479 end 2480 2481 # Warnings 2482 2483 %w[author description email homepage summary].each do |attribute| 2484 value = self.send attribute 2485 alert_warning "no #{attribute} specified" if value.nil? or value.empty? 2486 end 2487 2488 if description == summary then 2489 alert_warning 'description and summary are identical' 2490 end 2491 2492 # TODO: raise at some given date 2493 alert_warning "deprecated autorequire specified" if autorequire 2494 2495 executables.each do |executable| 2496 executable_path = File.join(bindir, executable) 2497 shebang = File.read(executable_path, 2) == '#!' 2498 2499 alert_warning "#{executable_path} is missing #! line" unless shebang 2500 end 2501 2502 dependencies.each do |dep| 2503 prerelease_dep = dep.requirements_list.any? do |req| 2504 Gem::Requirement.new(req).prerelease? 2505 end 2506 2507 alert_warning "prerelease dependency on #{dep} is not recommended" if 2508 prerelease_dep 2509 end 2510 2511 true 2512 end 2513 2514 ## 2515 # Checks to see if the files to be packaged are world-readable. 2516 2517 def validate_permissions 2518 return if Gem.win_platform? 2519 2520 files.each do |file| 2521 next if File.stat(file).mode & 0444 == 0444 2522 alert_warning "#{file} is not world-readable" 2523 end 2524 2525 executables.each do |name| 2526 exec = File.join @bindir, name 2527 next if File.stat(exec).executable? 2528 alert_warning "#{exec} is not executable" 2529 end 2530 end 2531 2532 ## 2533 # Set the version to +version+, potentially also setting 2534 # required_rubygems_version if +version+ indicates it is a 2535 # prerelease. 2536 2537 def version= version 2538 @version = Gem::Version.create(version) 2539 self.required_rubygems_version = '> 1.3.1' if @version.prerelease? 2540 invalidate_memoized_attributes 2541 2542 return @version 2543 end 2544 2545 # FIX: have this handle the platform/new_platform/original_platform bullshit 2546 def yaml_initialize(tag, vals) # :nodoc: 2547 vals.each do |ivar, val| 2548 case ivar 2549 when "date" 2550 # Force Date to go through the extra coerce logic in date= 2551 self.date = val.untaint 2552 else 2553 instance_variable_set "@#{ivar}", val.untaint 2554 end 2555 end 2556 2557 @original_platform = @platform # for backwards compatibility 2558 self.platform = Gem::Platform.new @platform 2559 end 2560 2561 ## 2562 # Reset nil attributes to their default values to make the spec valid 2563 2564 def reset_nil_attributes_to_default 2565 nil_attributes = self.class.non_nil_attributes.find_all do |name| 2566 !instance_variable_defined?("@#{name}") || instance_variable_get("@#{name}").nil? 2567 end 2568 2569 nil_attributes.each do |attribute| 2570 default = self.default_value attribute 2571 2572 value = case default 2573 when Time, Numeric, Symbol, true, false, nil then default 2574 else default.dup 2575 end 2576 2577 instance_variable_set "@#{attribute}", value 2578 end 2579 end 2580 2581 def default_gem? 2582 loaded_from && 2583 File.dirname(loaded_from) == self.class.default_specifications_dir 2584 end 2585 2586 extend Gem::Deprecate 2587 2588 # TODO: 2589 # deprecate :has_rdoc, :none, 2011, 10 2590 # deprecate :has_rdoc?, :none, 2011, 10 2591 # deprecate :has_rdoc=, :none, 2011, 10 2592 # deprecate :default_executable, :none, 2011, 10 2593 # deprecate :default_executable=, :none, 2011, 10 2594 # deprecate :file_name, :cache_file, 2011, 10 2595 # deprecate :full_gem_path, :cache_file, 2011, 10 2596end 2597 2598# DOC: What is this and why is it here, randomly, at the end of this file? 2599Gem.clear_paths 2600