Class | Gem::Specification |
In: |
lib/rubygems/specification.rb
|
Parent: | Object |
The Specification class contains the metadata for a Gem. Typically defined in a .gemspec file or a Rakefile, and looks like this:
spec = Gem::Specification.new do |s| s.name = 'example' s.version = '1.0' s.summary = 'Example gem specification' ... end
For a great way to package gems, use Hoe.
NONEXISTENT_SPECIFICATION_VERSION | = | -1 | The the version number of a specification that does not specify one (i.e. RubyGems 0.7 or earlier). | |
CURRENT_SPECIFICATION_VERSION | = | 3 |
The specification version applied to any new Specification instances created. This should
be bumped whenever something in the spec format changes.
Specification Version History: spec ruby ver ver yyyy-mm-dd description -1 <0.8.0 pre-spec-version-history 1 0.8.0 2004-08-01 Deprecated "test_suite_file" for "test_files" "test_file=x" is a shortcut for "test_files=[x]" 2 0.9.5 2007-10-01 Added "required_rubygems_version" Now forward-compatible with future versions 3 1.3.2 2009-01-03 Added Fixnum validation to specification_version |
name | [RW] | This gem‘s name |
require_paths | [RW] |
Paths in the gem to add to $LOAD_PATH when this gem is activated.
The default [‘lib’] is typically sufficient. |
rubygems_version | [RW] |
The version of RubyGems used to create this gem.
Do not set this, it is set automatically when the gem is packaged. |
specification_version | [RW] |
The Gem::Specification version of this
gemspec.
Do not set this, it is set automatically when the gem is packaged. |
summary | [R] |
A short summary of this gem‘s description. Displayed in `gem list
-d`.
The description should be more detailed than the summary. For example, you might wish to copy the entire README into the description. |
version | [R] | This gem‘s version |
loaded | -> | loaded? |
activated | -> | activated? |
activated | [RW] | True when this gemspec has been activated. This attribute is not persisted. |
autorequire | [RW] |
Autorequire was used by old RubyGems to automatically require a file.
Deprecated: It is neither supported nor functional. |
bindir | [RW] | The path in the gem for executable scripts. Usually ‘bin‘ |
cert_chain | [RW] | The certificate chain used to sign this gem. See Gem::Security for details. |
default_executable | [W] |
Sets the default executable for
this gem.
Deprecated: You must now specify the executable name to Gem.bin_path. |
description | [R] | A long description of this gem |
[RW] |
A contact email for this gem
If you are providing multiple authors and multiple emails they should be in the same order such that: Hash[*spec.authors.zip(spec.emails).flatten] Gives a hash of author name to email address. |
|
homepage | [RW] | The URL of this gem‘s home page |
loaded_from | [R] | Path this gemspec was loaded from. This attribute is not persisted. |
post_install_message | [RW] | A message that gets displayed after the gem is installed |
required_ruby_version | [R] | The version of ruby required by this gem |
required_rubygems_version | [R] | The RubyGems version required by this gem |
rubyforge_project | [RW] | The rubyforge project this gem lives under. i.e. RubyGems’ rubyforge_project is "rubygems". |
signing_key | [RW] | The key used to sign this gem. See Gem::Security for details. |
Load custom marshal format, re-initializing defaults as needed
# File lib/rubygems/specification.rb, line 648 648: def self._load(str) 649: array = Marshal.load str 650: 651: spec = Gem::Specification.new 652: spec.instance_variable_set :@specification_version, array[1] 653: 654: current_version = CURRENT_SPECIFICATION_VERSION 655: 656: field_count = if spec.specification_version > current_version then 657: spec.instance_variable_set :@specification_version, 658: current_version 659: MARSHAL_FIELDS[current_version] 660: else 661: MARSHAL_FIELDS[spec.specification_version] 662: end 663: 664: if array.size < field_count then 665: raise TypeError, "invalid Gem::Specification format #{array.inspect}" 666: end 667: 668: spec.instance_variable_set :@rubygems_version, array[0] 669: # spec version 670: spec.instance_variable_set :@name, array[2] 671: spec.instance_variable_set :@version, array[3] 672: spec.instance_variable_set :@date, array[4] 673: spec.instance_variable_set :@summary, array[5] 674: spec.instance_variable_set :@required_ruby_version, array[6] 675: spec.instance_variable_set :@required_rubygems_version, array[7] 676: spec.instance_variable_set :@original_platform, array[8] 677: spec.instance_variable_set :@dependencies, array[9] 678: spec.instance_variable_set :@rubyforge_project, array[10] 679: spec.instance_variable_set :@email, array[11] 680: spec.instance_variable_set :@authors, array[12] 681: spec.instance_variable_set :@description, array[13] 682: spec.instance_variable_set :@homepage, array[14] 683: spec.instance_variable_set :@has_rdoc, array[15] 684: spec.instance_variable_set :@new_platform, array[16] 685: spec.instance_variable_set :@platform, array[16].to_s 686: spec.instance_variable_set :@license, array[17] 687: spec.instance_variable_set :@loaded, false 688: spec.instance_variable_set :@activated, false 689: 690: spec 691: end
Adds spec to the known specifications, keeping the collection properly sorted.
# File lib/rubygems/specification.rb, line 294 294: def self.add_spec spec 295: # TODO: find all extraneous adds 296: # puts 297: # p :add_spec => [spec.full_name, caller.reject { |s| s =~ /minitest/ }] 298: 299: # TODO: flush the rest of the crap from the tests 300: # raise "no dupes #{spec.full_name} in #{all_names.inspect}" if 301: # _all.include? spec 302: 303: raise "nil spec!" unless spec # TODO: remove once we're happy with tests 304: 305: return if _all.include? spec 306: 307: _all << spec 308: _resort! 309: end
Adds multiple specs to the known specifications.
# File lib/rubygems/specification.rb, line 314 314: def self.add_specs *specs 315: raise "nil spec!" if specs.any?(&:nil?) # TODO: remove once we're happy 316: 317: # TODO: this is much more efficient, but we need the extra checks for now 318: # _all.concat specs 319: # _resort! 320: 321: specs.each do |spec| # TODO: slow 322: add_spec spec 323: end 324: end
Returns all specifications. This method is discouraged from use. You probably want to use one of the Enumerable methods instead.
# File lib/rubygems/specification.rb, line 330 330: def self.all 331: warn "NOTE: Specification.all called from #{caller.first}" unless 332: Gem::Deprecate.skip 333: _all 334: end
Sets the known specs to specs. Not guaranteed to work for you in the future. Use at your own risk. Caveat emptor. Doomy doom doom. Etc etc.
# File lib/rubygems/specification.rb, line 348 348: def self.all= specs 349: @@all = specs 350: end
Return the directories that Specification uses to find specs.
# File lib/rubygems/specification.rb, line 380 380: def self.dirs 381: @@dirs ||= Gem.path.collect { |dir| 382: File.join dir, "specifications" 383: } 384: end
Set the directories that Specification uses to find specs. Setting this resets the list of known specs.
# File lib/rubygems/specification.rb, line 390 390: def self.dirs= dirs 391: # TODO: find extra calls to dir= 392: # warn "NOTE: dirs= called from #{caller.first} for #{dirs.inspect}" 393: 394: self.reset 395: 396: # ugh 397: @@dirs = Array(dirs).map { |dir| File.join dir, "specifications" } 398: end
Returns every spec that matches name and optional requirements.
# File lib/rubygems/specification.rb, line 417 417: def self.find_all_by_name name, *requirements 418: requirements = Gem::Requirement.default if requirements.empty? 419: 420: # TODO: maybe try: find_all { |s| spec === dep } 421: 422: Gem::Dependency.new(name, *requirements).matching_specs 423: end
Find the best specification matching a name and requirements. Raises if the dependency doesn‘t resolve to a valid specification.
# File lib/rubygems/specification.rb, line 429 429: def self.find_by_name name, *requirements 430: requirements = Gem::Requirement.default if requirements.empty? 431: 432: # TODO: maybe try: find { |s| spec === dep } 433: 434: Gem::Dependency.new(name, *requirements).to_spec 435: end
Return the best specification that contains the file matching path.
# File lib/rubygems/specification.rb, line 440 440: def self.find_by_path path 441: self.find { |spec| 442: spec.contains_requirable_file? path 443: } 444: end
Return currently unresolved specs that contain the file matching path.
# File lib/rubygems/specification.rb, line 449 449: def self.find_in_unresolved path 450: # TODO: do we need these?? Kill it 451: specs = Gem.unresolved_deps.values.map { |dep| dep.to_specs }.flatten 452: 453: specs.find_all { |spec| spec.contains_requirable_file? path } 454: end
Search through all unresolved deps and sub-dependencies and return specs that contain the file matching path.
# File lib/rubygems/specification.rb, line 460 460: def self.find_in_unresolved_tree path 461: specs = Gem.unresolved_deps.values.map { |dep| dep.to_specs }.flatten 462: 463: specs.reverse_each do |spec| 464: trails = [] 465: spec.traverse do |from_spec, dep, to_spec, trail| 466: next unless to_spec.conflicts.empty? 467: trails << trail if to_spec.contains_requirable_file? path 468: end 469: 470: next if trails.empty? 471: 472: return trails.map(&:reverse).sort.first.reverse 473: end 474: 475: [] 476: end
Special loader for YAML files. When a Specification object is loaded from a YAML file, it bypasses the normal Ruby object initialization routine (initialize). This method makes up for that and deals with gems of different ages.
input can be anything that YAML.load() accepts: String or IO.
# File lib/rubygems/specification.rb, line 486 486: def self.from_yaml(input) 487: Gem.load_yaml 488: 489: input = normalize_yaml_input input 490: spec = YAML.load input 491: 492: if spec && spec.class == FalseClass then 493: raise Gem::EndOfYAMLException 494: end 495: 496: unless Gem::Specification === spec then 497: raise Gem::Exception, "YAML data doesn't evaluate to gem specification" 498: end 499: 500: unless (spec.instance_variables.include? '@specification_version' or 501: spec.instance_variables.include? :@specification_version) and 502: spec.instance_variable_get :@specification_version 503: spec.instance_variable_set :@specification_version, 504: NONEXISTENT_SPECIFICATION_VERSION 505: end 506: 507: spec 508: end
Return the latest specs, optionally including prerelease specs if prerelease is true.
# File lib/rubygems/specification.rb, line 514 514: def self.latest_specs prerelease = false 515: result = Hash.new { |h,k| h[k] = {} } 516: native = {} 517: 518: Gem::Specification._all.reverse_each do |spec| 519: next if spec.version.prerelease? unless prerelease 520: 521: native[spec.name] = spec.version if spec.platform == Gem::Platform::RUBY 522: result[spec.name][spec.platform] = spec 523: end 524: 525: result.map(&:last).map(&:values).flatten.reject { |spec| 526: minimum = native[spec.name] 527: minimum && spec.version < minimum 528: } 529: end
Loads Ruby format gemspec from file.
# File lib/rubygems/specification.rb, line 534 534: def self.load file 535: return unless file && File.file?(file) 536: 537: file = file.dup.untaint 538: 539: code = if defined? Encoding 540: File.read file, :encoding => "UTF-8" 541: else 542: File.read file 543: end 544: 545: code.untaint 546: 547: begin 548: spec = eval code, binding, file 549: 550: if Gem::Specification === spec 551: spec.loaded_from = file.to_s 552: return spec 553: end 554: 555: warn "[#{file}] isn't a Gem::Specification (#{spec.class} instead)." 556: rescue SignalException, SystemExit 557: raise 558: rescue SyntaxError, Exception => e 559: warn "Invalid gemspec in [#{file}]: #{e}" 560: end 561: 562: nil 563: end
Specification constructor. Assigns the default values to the attributes and yields itself for further initialization. Optionally takes name and version.
# File lib/rubygems/specification.rb, line 1331 1331: def initialize name = nil, version = nil 1332: @loaded = false 1333: @activated = false 1334: @loaded_from = nil 1335: @original_platform = nil 1336: 1337: @@nil_attributes.each do |key| 1338: instance_variable_set "@#{key}", nil 1339: end 1340: 1341: @@non_nil_attributes.each do |key| 1342: default = default_value(key) 1343: value = case default 1344: when Time, Numeric, Symbol, true, false, nil then default 1345: else default.dup 1346: end 1347: 1348: instance_variable_set "@#{key}", value 1349: end 1350: 1351: @new_platform = Gem::Platform::RUBY 1352: 1353: self.name = name if name 1354: self.version = version if version 1355: 1356: yield self if block_given? 1357: end
Specification attributes that must be non-nil
# File lib/rubygems/specification.rb, line 568 568: def self.non_nil_attributes 569: @@non_nil_attributes.dup 570: end
Make sure the YAML specification is properly formatted with dashes
# File lib/rubygems/specification.rb, line 575 575: def self.normalize_yaml_input(input) 576: result = input.respond_to?(:read) ? input.read : input 577: result = "--- " + result unless result =~ /\A--- / 578: result.gsub!(/ !!null \n/, " \n") 579: # date: 2011-04-26 00:00:00.000000000Z 580: # date: 2011-04-26 00:00:00.000000000 Z 581: result.gsub!(/^(date: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+?)Z/, '\1 Z') 582: result 583: end
Return a list of all outdated specifications. This method is HEAVY as it must go fetch specifications from the server.
# File lib/rubygems/specification.rb, line 589 589: def self.outdated 590: outdateds = [] 591: 592: # TODO: maybe we should switch to rubygems' version service? 593: fetcher = Gem::SpecFetcher.fetcher 594: 595: latest_specs.each do |local| 596: dependency = Gem::Dependency.new local.name, ">= #{local.version}" 597: remotes = fetcher.find_matching dependency 598: remotes = remotes.map { |(_, version, _), _| version } 599: latest = remotes.sort.last 600: 601: outdateds << local.name if latest and local.version < latest 602: end 603: 604: outdateds 605: end
Removes spec from the known specs.
# File lib/rubygems/specification.rb, line 610 610: def self.remove_spec spec 611: # TODO: beat on the tests 612: raise "wtf: #{spec.full_name} not in #{all_names.inspect}" unless 613: _all.include? spec 614: _all.delete spec 615: end
Is name a required attribute?
# File lib/rubygems/specification.rb, line 620 620: def self.required_attribute?(name) 621: @@required_attributes.include? name.to_sym 622: end
Required specification attributes
# File lib/rubygems/specification.rb, line 627 627: def self.required_attributes 628: @@required_attributes.dup 629: end
Reset the list of known specs, running pre and post reset hooks registered in Gem.
# File lib/rubygems/specification.rb, line 635 635: def self.reset 636: @@dirs = nil 637: # from = caller.first(10).reject { |s| s =~ /minitest/ } 638: # warn "" 639: # warn "NOTE: Specification.reset from #{from.inspect}" 640: Gem.pre_reset_hooks.each { |hook| hook.call } 641: @@all = nil 642: Gem.post_reset_hooks.each { |hook| hook.call } 643: end
Dump only crucial instance variables.
# File lib/rubygems/specification.rb, line 710 710: def _dump(limit) 711: Marshal.dump [ 712: @rubygems_version, 713: @specification_version, 714: @name, 715: @version, 716: date, 717: @summary, 718: @required_ruby_version, 719: @required_rubygems_version, 720: @original_platform, 721: @dependencies, 722: @rubyforge_project, 723: @email, 724: @authors, 725: @description, 726: @homepage, 727: true, # has_rdoc 728: @new_platform, 729: @licenses 730: ] 731: end
Activate this spec, registering it as a loaded spec and adding it‘s lib paths to $LOAD_PATH. Returns true if the spec was activated, false if it was previously activated. Freaks out if there are conflicts upon activation.
# File lib/rubygems/specification.rb, line 739 739: def activate 740: raise_if_conflicts 741: 742: return false if Gem.loaded_specs[self.name] 743: 744: activate_dependencies 745: add_self_to_load_path 746: 747: Gem.loaded_specs[self.name] = self 748: @activated = true 749: @loaded = true 750: 751: return true 752: end
Activate all unambiguously resolved runtime dependencies of this spec. Add any ambigous dependencies to the unresolved list to be resolved later, as needed.
# File lib/rubygems/specification.rb, line 759 759: def activate_dependencies 760: self.runtime_dependencies.each do |spec_dep| 761: if loaded = Gem.loaded_specs[spec_dep.name] 762: next if spec_dep.matches_spec? loaded 763: 764: msg = "can't satisfy '#{spec_dep}', already activated '#{loaded.full_name}'" 765: e = Gem::LoadError.new msg 766: e.name = spec_dep.name 767: 768: raise e 769: end 770: 771: specs = spec_dep.to_specs 772: 773: if specs.size == 1 then 774: specs.first.activate 775: else 776: name = spec_dep.name 777: Gem.unresolved_deps[name] = Gem.unresolved_deps[name].merge spec_dep 778: end 779: end 780: 781: Gem.unresolved_deps.delete self.name 782: end
Returns an array with bindir attached to each executable in the executables list
# File lib/rubygems/specification.rb, line 788 788: def add_bindir(executables) 789: return nil if executables.nil? 790: 791: if @bindir then 792: Array(executables).map { |e| File.join(@bindir, e) } 793: else 794: executables 795: end 796: rescue 797: return nil 798: end
Adds a development dependency named gem with requirements to this Gem. For example:
spec.add_development_dependency 'example', '~> 1.1', '>= 1.1.4'
Development dependencies aren‘t installed by default and aren‘t activated when a gem is required.
# File lib/rubygems/specification.rb, line 832 832: def add_development_dependency(gem, *requirements) 833: add_dependency_with_type(gem, :development, *requirements) 834: end
Adds a runtime dependency named gem with requirements to this Gem. For example:
spec.add_runtime_dependency 'example', '~> 1.1', '>= 1.1.4'
# File lib/rubygems/specification.rb, line 842 842: def add_runtime_dependency(gem, *requirements) 843: add_dependency_with_type(gem, :runtime, *requirements) 844: end
Adds this spec‘s require paths to LOAD_PATH, in the proper location.
# File lib/rubygems/specification.rb, line 851 851: def add_self_to_load_path 852: paths = require_paths.map do |path| 853: File.join full_gem_path, path 854: end 855: 856: # gem directories must come after -I and ENV['RUBYLIB'] 857: insert_index = Gem.load_path_insert_index 858: 859: if insert_index then 860: # gem directories must come after -I and ENV['RUBYLIB'] 861: $LOAD_PATH.insert(insert_index, *paths) 862: else 863: # we are probably testing in core, -I and RUBYLIB don't apply 864: $LOAD_PATH.unshift(*paths) 865: end 866: end
The list of author names who wrote this gem.
If you are providing multiple authors and multiple emails they should be in the same order such that:
Hash[*spec.authors.zip(spec.emails).flatten]
Gives a hash of author name to email address.
# File lib/rubygems/specification.rb, line 892 892: def authors 893: @authors ||= [] 894: end
Returns the full path to the base gem directory.
eg: /usr/local/lib/ruby/gems/1.8
# File lib/rubygems/specification.rb, line 908 908: def base_dir 909: return Gem.dir unless loaded_from 910: @base_dir ||= File.dirname File.dirname loaded_from 911: end
Returns the full path to installed gem‘s bin directory.
NOTE: do not confuse this with bindir, which is just ‘bin’, not a full path.
# File lib/rubygems/specification.rb, line 919 919: def bin_dir 920: @bin_dir ||= File.join gem_dir, bindir # TODO: this is unfortunate 921: end
Returns the full path to an executable named name in this gem.
# File lib/rubygems/specification.rb, line 926 926: def bin_file name 927: File.join bin_dir, name 928: end
Returns the full path to the cache directory containing this spec‘s cached gem.
# File lib/rubygems/specification.rb, line 934 934: def cache_dir 935: @cache_dir ||= File.join base_dir, "cache" 936: end
Returns the full path to the cached gem for this spec.
# File lib/rubygems/specification.rb, line 941 941: def cache_file 942: @cache_file ||= File.join cache_dir, "#{full_name}.gem" 943: end
Return any possible conflicts against the currently loaded specs.
# File lib/rubygems/specification.rb, line 950 950: def conflicts 951: conflicts = {} 952: Gem.loaded_specs.values.each do |spec| 953: bad = self.runtime_dependencies.find_all { |dep| 954: spec.name == dep.name and not spec.satisfies_requirement? dep 955: } 956: 957: conflicts[spec] = bad unless bad.empty? 958: end 959: conflicts 960: end
Return true if this spec can require file.
# File lib/rubygems/specification.rb, line 965 965: def contains_requirable_file? file 966: root = full_gem_path 967: 968: require_paths.each do |lib| 969: base = "#{root}/#{lib}/#{file}" 970: Gem.suffixes.each do |suf| 971: path = "#{base}#{suf}" 972: return true if File.file? path 973: end 974: end 975: 976: return false 977: end
The date this gem was created
Do not set this, it is set automatically when the gem is packaged.
# File lib/rubygems/specification.rb, line 991 991: def date= date 992: # We want to end up with a Time object with one-day resolution. 993: # This is the cleanest, most-readable, faster-than-using-Date 994: # way to do it. 995: @date = case date 996: when String then 997: if /\A(\d{4})-(\d{2})-(\d{2})\Z/ =~ date then 998: Time.utc($1.to_i, $2.to_i, $3.to_i) 999: else 1000: raise(Gem::InvalidSpecificationException, 1001: "invalid date format in specification: #{date.inspect}") 1002: end 1003: when Time, Date then 1004: Time.utc(date.year, date.month, date.day) 1005: else 1006: TODAY 1007: end 1008: end
The default executable for this gem.
Deprecated: The name of the gem is assumed to be the name of the executable now. See Gem.bin_path.
# File lib/rubygems/specification.rb, line 1016 1016: def default_executable 1017: if defined?(@default_executable) and @default_executable 1018: result = @default_executable 1019: elsif @executables and @executables.size == 1 1020: result = Array(@executables).first 1021: else 1022: result = nil 1023: end 1024: result 1025: end
The default value for specification attribute name
# File lib/rubygems/specification.rb, line 1030 1030: def default_value name 1031: @@default_value[name] 1032: end
A list of Gem::Dependency objects this gem depends on.
Use add_dependency or add_development_dependency to add dependencies to a gem.
# File lib/rubygems/specification.rb, line 1040 1040: def dependencies 1041: @dependencies ||= [] 1042: end
Return a list of all gems that have a dependency on this gemspec. The list is structured with entries that conform to:
[depending_gem, dependency, [list_of_gems_that_satisfy_dependency]]
# File lib/rubygems/specification.rb, line 1050 1050: def dependent_gems 1051: out = [] 1052: Gem::Specification.each do |spec| 1053: spec.dependencies.each do |dep| 1054: if self.satisfies_requirement?(dep) then 1055: sats = [] 1056: find_all_satisfiers(dep) do |sat| 1057: sats << sat 1058: end 1059: out << [spec, dep, sats] 1060: end 1061: end 1062: end 1063: out 1064: end
Returns all specs that matches this spec‘s runtime dependencies.
# File lib/rubygems/specification.rb, line 1069 1069: def dependent_specs 1070: runtime_dependencies.map { |dep| dep.to_specs }.flatten 1071: end
A long description of this gem
# File lib/rubygems/specification.rb, line 1076 1076: def description= str 1077: @description = str.to_s 1078: end
List of dependencies that are used for development
# File lib/rubygems/specification.rb, line 1083 1083: def development_dependencies 1084: dependencies.select { |d| d.type == :development } 1085: end
Returns the full path to this spec‘s documentation directory.
# File lib/rubygems/specification.rb, line 1090 1090: def doc_dir 1091: @doc_dir ||= File.join base_dir, 'doc', full_name 1092: end
Singular accessor for executables
# File lib/rubygems/specification.rb, line 1122 1122: def executable 1123: val = executables and val.first 1124: end
Singular accessor for executables
# File lib/rubygems/specification.rb, line 1129 1129: def executable=o 1130: self.executables = [o] 1131: end
Executables included in the gem.
# File lib/rubygems/specification.rb, line 1136 1136: def executables 1137: @executables ||= [] 1138: end
Sets executables to value, ensuring it is an array. Don‘t use this, push onto the array instead.
# File lib/rubygems/specification.rb, line 1144 1144: def executables= value 1145: # TODO: warn about setting instead of pushing 1146: @executables = Array(value) 1147: end
Extensions to build when installing the gem. See Gem::Installer#build_extensions for valid values.
# File lib/rubygems/specification.rb, line 1153 1153: def extensions 1154: @extensions ||= [] 1155: end
Sets extensions to extensions, ensuring it is an array. Don‘t use this, push onto the array instead.
# File lib/rubygems/specification.rb, line 1161 1161: def extensions= extensions 1162: # TODO: warn about setting instead of pushing 1163: @extensions = Array extensions 1164: end
Sets extra_rdoc_files to files, ensuring it is an array. Don‘t use this, push onto the array instead.
# File lib/rubygems/specification.rb, line 1177 1177: def extra_rdoc_files= files 1178: # TODO: warn about setting instead of pushing 1179: @extra_rdoc_files = Array files 1180: end
Files included in this gem. You cannot append to this accessor, you must assign to it.
Only add files you can require to this list, not directories, etc.
Directories are automatically stripped from this list when building a gem, other non-files cause an error.
# File lib/rubygems/specification.rb, line 1200 1200: def files 1201: # DO NOT CHANGE TO ||= ! This is not a normal accessor. (yes, it sucks) 1202: @files = [@files, 1203: @test_files, 1204: add_bindir(@executables), 1205: @extra_rdoc_files, 1206: @extensions, 1207: ].flatten.uniq.compact 1208: end
Creates a duplicate spec without large blobs that aren‘t used at runtime.
# File lib/rubygems/specification.rb, line 1231 1231: def for_cache 1232: spec = dup 1233: 1234: spec.files = nil 1235: spec.test_files = nil 1236: 1237: spec 1238: end
The full path to the gem (install path + full name).
# File lib/rubygems/specification.rb, line 1243 1243: def full_gem_path 1244: # TODO: try to get rid of this... or the awkward 1245: # TODO: also, shouldn't it default to full_name if it hasn't been written? 1246: return @full_gem_path if defined?(@full_gem_path) && @full_gem_path 1247: 1248: @full_gem_path = File.expand_path File.join(gems_dir, full_name) 1249: 1250: return @full_gem_path if File.directory? @full_gem_path 1251: 1252: @full_gem_path = File.expand_path File.join(gems_dir, original_name) 1253: end
Returns the full name (name-version) of this Gem. Platform information is included (name-version-platform) if it is specified and not the default Ruby platform.
# File lib/rubygems/specification.rb, line 1260 1260: def full_name 1261: if platform == Gem::Platform::RUBY or platform.nil? then 1262: "#{@name}-#{@version}" 1263: else 1264: "#{@name}-#{@version}-#{platform}" 1265: end 1266: end
Returns the full path to this spec‘s gem directory. eg: /usr/local/lib/ruby/1.8/gems/mygem-1.0
# File lib/rubygems/specification.rb, line 1272 1272: def gem_dir 1273: @gem_dir ||= File.expand_path File.join(gems_dir, full_name) 1274: end
Returns the full path to the gems directory containing this spec‘s gem directory. eg: /usr/local/lib/ruby/1.8/gems
# File lib/rubygems/specification.rb, line 1280 1280: def gems_dir 1281: # TODO: this logic seems terribly broken, but tests fail if just base_dir 1282: @gems_dir ||= File.join(loaded_from && base_dir || Gem.dir, "gems") 1283: end
Deprecated and ignored, defaults to true.
Formerly used to indicate this gem was RDoc-capable.
# File lib/rubygems/specification.rb, line 1290 1290: def has_rdoc 1291: true 1292: end
Deprecated and ignored.
Formerly used to indicate this gem was RDoc-capable.
# File lib/rubygems/specification.rb, line 1299 1299: def has_rdoc= ignored 1300: @has_rdoc = true 1301: end
True if this gem has files in test_files
# File lib/rubygems/specification.rb, line 1308 1308: def has_unit_tests? 1309: not test_files.empty? 1310: end
Duplicates array_attributes from other_spec so state isn‘t shared.
# File lib/rubygems/specification.rb, line 1362 1362: def initialize_copy other_spec 1363: other_ivars = other_spec.instance_variables 1364: other_ivars = other_ivars.map { |ivar| ivar.intern } if # for 1.9 1365: String === other_ivars.first 1366: 1367: self.class.array_attributes.each do |name| 1368: name = "@#{name}""@#{name}" 1369: next unless other_ivars.include? name 1370: 1371: begin 1372: val = other_spec.instance_variable_get(name) 1373: if val then 1374: instance_variable_set name, val.dup 1375: else 1376: warn "WARNING: #{full_name} has an invalid nil value for #{name}" 1377: end 1378: rescue TypeError 1379: e = Gem::FormatException.new \ 1380: "#{full_name} has an invalid value for #{name}" 1381: 1382: e.file_path = loaded_from 1383: raise e 1384: end 1385: end 1386: end
Returns a string usable in Dir.glob to match all requirable paths for this spec.
# File lib/rubygems/specification.rb, line 1400 1400: def lib_dirs_glob 1401: dirs = if self.require_paths.size > 1 then 1402: "{#{self.require_paths.join(',')}}" 1403: else 1404: self.require_paths.first 1405: end 1406: 1407: "#{self.full_gem_path}/#{dirs}" 1408: end
Set the location a Specification was loaded from. obj is converted to a String.
# File lib/rubygems/specification.rb, line 1454 1454: def loaded_from= path 1455: @loaded_from = path.to_s 1456: end
Sets the rubygems_version to the current RubyGems version.
# File lib/rubygems/specification.rb, line 1461 1461: def mark_version 1462: @rubygems_version = Gem::VERSION 1463: end
Return all files in this gem that match for glob.
# File lib/rubygems/specification.rb, line 1468 1468: def matches_for_glob glob # TODO: rename? 1469: # TODO: do we need these?? Kill it 1470: glob = File.join(self.lib_dirs_glob, glob) 1471: 1472: Dir[glob].map { |f| f.untaint } # FIX our tests are broken, run w/ SAFE=1 1473: end
Normalize the list of files so that:
# File lib/rubygems/specification.rb, line 1493 1493: def normalize 1494: if defined?(@extra_rdoc_files) and @extra_rdoc_files then 1495: @extra_rdoc_files.uniq! 1496: @files ||= [] 1497: @files.concat(@extra_rdoc_files) 1498: end 1499: 1500: @files = @files.uniq if @files 1501: @extensions = @extensions.uniq if @extensions 1502: @test_files = @test_files.uniq if @test_files 1503: @executables = @executables.uniq if @executables 1504: @extra_rdoc_files = @extra_rdoc_files.uniq if @extra_rdoc_files 1505: end
The platform this gem runs on. See Gem::Platform for details.
# File lib/rubygems/specification.rb, line 1529 1529: def platform 1530: @new_platform ||= Gem::Platform::RUBY 1531: end
The platform this gem runs on. See Gem::Platform for details.
Setting this to any value other than Gem::Platform::RUBY or Gem::Platform::CURRENT is probably wrong.
# File lib/rubygems/specification.rb, line 1539 1539: def platform= platform 1540: if @original_platform.nil? or 1541: @original_platform == Gem::Platform::RUBY then 1542: @original_platform = platform 1543: end 1544: 1545: case platform 1546: when Gem::Platform::CURRENT then 1547: @new_platform = Gem::Platform.local 1548: @original_platform = @new_platform.to_s 1549: 1550: when Gem::Platform then 1551: @new_platform = platform 1552: 1553: # legacy constants 1554: when nil, Gem::Platform::RUBY then 1555: @new_platform = Gem::Platform::RUBY 1556: when 'mswin32' then # was Gem::Platform::WIN32 1557: @new_platform = Gem::Platform.new 'x86-mswin32' 1558: when 'i586-linux' then # was Gem::Platform::LINUX_586 1559: @new_platform = Gem::Platform.new 'x86-linux' 1560: when 'powerpc-darwin' then # was Gem::Platform::DARWIN 1561: @new_platform = Gem::Platform.new 'ppc-darwin' 1562: else 1563: @new_platform = Gem::Platform.new platform 1564: end 1565: 1566: @platform = @new_platform.to_s 1567: 1568: @new_platform 1569: end
Check the spec for possible conflicts and freak out if there are any.
# File lib/rubygems/specification.rb, line 1600 1600: def raise_if_conflicts 1601: other = Gem.loaded_specs[self.name] 1602: 1603: if other and self.version != other.version then 1604: # This gem is already loaded. If the currently loaded gem is not in the 1605: # list of candidate gems, then we have a version conflict. 1606: 1607: msg = "can't activate #{full_name}, already activated #{other.full_name}" 1608: 1609: e = Gem::LoadError.new msg 1610: e.name = self.name 1611: # TODO: e.requirement = dep.requirement 1612: 1613: raise e 1614: end 1615: 1616: conf = self.conflicts 1617: 1618: unless conf.empty? then 1619: y = conf.map { |act,con| 1620: "#{act.full_name} conflicts with #{con.join(", ")}" 1621: }.join ", " 1622: 1623: # TODO: improve message by saying who activated `con` 1624: 1625: raise Gem::LoadError, "Unable to activate #{self.full_name}, because #{y}" 1626: end 1627: end
An ARGV style array of options to RDoc
# File lib/rubygems/specification.rb, line 1632 1632: def rdoc_options 1633: @rdoc_options ||= [] 1634: end
Sets rdoc_options to value, ensuring it is an array. Don‘t use this, push onto the array instead.
# File lib/rubygems/specification.rb, line 1640 1640: def rdoc_options= options 1641: # TODO: warn about setting instead of pushing 1642: @rdoc_options = Array options 1643: end
Singular accessor for require_paths
# File lib/rubygems/specification.rb, line 1648 1648: def require_path 1649: val = require_paths and val.first 1650: end
Singular accessor for require_paths
# File lib/rubygems/specification.rb, line 1655 1655: def require_path= path 1656: self.require_paths = [path] 1657: end
The version of ruby required by this gem
# File lib/rubygems/specification.rb, line 1662 1662: def required_ruby_version= req 1663: @required_ruby_version = Gem::Requirement.create req 1664: end
The RubyGems version required by this gem
# File lib/rubygems/specification.rb, line 1669 1669: def required_rubygems_version= req 1670: @required_rubygems_version = Gem::Requirement.create req 1671: end
An array or things required by this gem. Not used by anything presently.
# File lib/rubygems/specification.rb, line 1677 1677: def requirements 1678: @requirements ||= [] 1679: end
Set requirements to req, ensuring it is an array. Don‘t use this, push onto the array instead.
# File lib/rubygems/specification.rb, line 1685 1685: def requirements= req 1686: # TODO: warn about setting instead of pushing 1687: @requirements = Array req 1688: end
Returns the full path to this spec‘s ri directory.
# File lib/rubygems/specification.rb, line 1693 1693: def ri_dir 1694: @ri_dir ||= File.join base_dir, 'ri', full_name 1695: end
List of dependencies that will automatically be activated at runtime.
# File lib/rubygems/specification.rb, line 1721 1721: def runtime_dependencies 1722: dependencies.select { |d| d.type == :runtime } 1723: end
Checks if this specification meets the requirement of dependency.
# File lib/rubygems/specification.rb, line 1737 1737: def satisfies_requirement? dependency 1738: return @name == dependency.name && 1739: dependency.requirement.satisfied_by?(@version) 1740: end
Returns an object you can use to sort specifications in sort_by.
# File lib/rubygems/specification.rb, line 1745 1745: def sort_obj 1746: # TODO: this is horrible. Deprecate it. 1747: [@name, @version, @new_platform == Gem::Platform::RUBY ? -1 : 1] 1748: end
Returns the full path to the directory containing this spec‘s gemspec file. eg: /usr/local/lib/ruby/gems/1.8/specifications
# File lib/rubygems/specification.rb, line 1754 1754: def spec_dir 1755: @spec_dir ||= File.join base_dir, "specifications" 1756: end
Returns the full path to this spec‘s gemspec file. eg: /usr/local/lib/ruby/gems/1.8/specifications/mygem-1.0.gemspec
# File lib/rubygems/specification.rb, line 1762 1762: def spec_file 1763: @spec_file ||= File.join spec_dir, "#{full_name}.gemspec" 1764: end
A short summary of this gem‘s description.
# File lib/rubygems/specification.rb, line 1778 1778: def summary= str 1779: @summary = str.to_s.strip. 1780: gsub(/(\w-)\n[ \t]*(\w)/, '\1\2').gsub(/\n[ \t]*/, " ") # so. weird. 1781: end
Singular accessor for test_files
# File lib/rubygems/specification.rb, line 1786 1786: def test_file 1787: val = test_files and val.first 1788: end
Singular accessor for test_files
# File lib/rubygems/specification.rb, line 1793 1793: def test_file= file 1794: self.test_files = [file] 1795: end
Test files included in this gem. You cannot append to this accessor, you must assign to it.
# File lib/rubygems/specification.rb, line 1801 1801: def test_files 1802: # Handle the possibility that we have @test_suite_file but not 1803: # @test_files. This will happen when an old gem is loaded via 1804: # YAML. 1805: if defined? @test_suite_file then 1806: @test_files = [@test_suite_file].flatten 1807: @test_suite_file = nil 1808: end 1809: if defined?(@test_files) and @test_files then 1810: @test_files 1811: else 1812: @test_files = [] 1813: end 1814: end
Set test_files to files, ensuring it is an array.
# File lib/rubygems/specification.rb, line 1819 1819: def test_files= files 1820: @test_files = Array files 1821: end
Returns a Ruby code representation of this specification, such that it can be eval‘ed and reconstruct the same specification later. Attributes that still have their default values are omitted.
# File lib/rubygems/specification.rb, line 1839 1839: def to_ruby 1840: mark_version 1841: result = [] 1842: result << "# -*- encoding: utf-8 -*-" 1843: result << nil 1844: result << "Gem::Specification.new do |s|" 1845: 1846: result << " s.name = #{ruby_code name}" 1847: result << " s.version = #{ruby_code version}" 1848: unless platform.nil? or platform == Gem::Platform::RUBY then 1849: result << " s.platform = #{ruby_code original_platform}" 1850: end 1851: result << "" 1852: result << " s.required_rubygems_version = #{ruby_code required_rubygems_version} if s.respond_to? :required_rubygems_version=" 1853: 1854: handled = [ 1855: :dependencies, 1856: :name, 1857: :platform, 1858: :required_rubygems_version, 1859: :specification_version, 1860: :version, 1861: :has_rdoc, 1862: :default_executable, 1863: ] 1864: 1865: @@attributes.each do |attr_name| 1866: next if handled.include? attr_name 1867: current_value = self.send(attr_name) 1868: if current_value != default_value(attr_name) or 1869: self.class.required_attribute? attr_name then 1870: result << " s.#{attr_name} = #{ruby_code current_value}" 1871: end 1872: end 1873: 1874: result << nil 1875: result << " if s.respond_to? :specification_version then" 1876: result << " s.specification_version = #{specification_version}" 1877: result << nil 1878: 1879: result << " if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then" 1880: 1881: dependencies.each do |dep| 1882: req = dep.requirements_list.inspect 1883: dep.instance_variable_set :@type, :runtime if dep.type.nil? # HACK 1884: result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>, #{req})" 1885: end 1886: 1887: result << " else" 1888: 1889: dependencies.each do |dep| 1890: version_reqs_param = dep.requirements_list.inspect 1891: result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})" 1892: end 1893: 1894: result << ' end' 1895: 1896: result << " else" 1897: dependencies.each do |dep| 1898: version_reqs_param = dep.requirements_list.inspect 1899: result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})" 1900: end 1901: result << " end" 1902: 1903: result << "end" 1904: result << nil 1905: 1906: result.join "\n" 1907: end
Recursively walk dependencies of this spec, executing the block for each hop.
# File lib/rubygems/specification.rb, line 1939 1939: def traverse trail = [], &block 1940: trail = trail + [self] 1941: runtime_dependencies.each do |dep| 1942: dep.to_specs.each do |dep_spec| 1943: block[self, dep, dep_spec, trail + [dep_spec]] 1944: dep_spec.traverse(trail, &block) unless 1945: trail.map(&:name).include? dep_spec.name 1946: end 1947: end 1948: end
Checks that the specification contains all required fields, and does a very basic sanity check.
Raises InvalidSpecificationException if the spec does not pass the checks..
# File lib/rubygems/specification.rb, line 1957 1957: def validate packaging = true 1958: require 'rubygems/user_interaction' 1959: extend Gem::UserInteraction 1960: normalize 1961: 1962: nil_attributes = self.class.non_nil_attributes.find_all do |name| 1963: instance_variable_get("@#{name}").nil? 1964: end 1965: 1966: unless nil_attributes.empty? then 1967: raise Gem::InvalidSpecificationException, 1968: "#{nil_attributes.join ', '} must not be nil" 1969: end 1970: 1971: if packaging and rubygems_version != Gem::VERSION then 1972: raise Gem::InvalidSpecificationException, 1973: "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}" 1974: end 1975: 1976: @@required_attributes.each do |symbol| 1977: unless self.send symbol then 1978: raise Gem::InvalidSpecificationException, 1979: "missing value for attribute #{symbol}" 1980: end 1981: end 1982: 1983: unless String === name then 1984: raise Gem::InvalidSpecificationException, 1985: "invalid value for attribute name: \"#{name.inspect}\"" 1986: end 1987: 1988: if require_paths.empty? then 1989: raise Gem::InvalidSpecificationException, 1990: 'specification must have at least one require_path' 1991: end 1992: 1993: @files.delete_if { |x| File.directory?(x) } 1994: @test_files.delete_if { |x| File.directory?(x) } 1995: @executables.delete_if { |x| File.directory?(File.join(@bindir, x)) } 1996: @extra_rdoc_files.delete_if { |x| File.directory?(x) } 1997: @extensions.delete_if { |x| File.directory?(x) } 1998: 1999: non_files = files.reject { |x| File.file?(x) } 2000: 2001: unless not packaging or non_files.empty? then 2002: raise Gem::InvalidSpecificationException, 2003: "[\"#{non_files.join "\", \""}\"] are not files" 2004: end 2005: 2006: unless specification_version.is_a?(Fixnum) 2007: raise Gem::InvalidSpecificationException, 2008: 'specification_version must be a Fixnum (did you mean version?)' 2009: end 2010: 2011: case platform 2012: when Gem::Platform, Gem::Platform::RUBY then # ok 2013: else 2014: raise Gem::InvalidSpecificationException, 2015: "invalid platform #{platform.inspect}, see Gem::Platform" 2016: end 2017: 2018: self.class.array_attributes.each do |field| 2019: val = self.send field 2020: klass = case field 2021: when :dependencies 2022: Gem::Dependency 2023: else 2024: String 2025: end 2026: 2027: unless Array === val and val.all? { |x| x.kind_of?(klass) } then 2028: raise(Gem::InvalidSpecificationException, 2029: "#{field} must be an Array of #{klass}") 2030: end 2031: end 2032: 2033: [:authors].each do |field| 2034: val = self.send field 2035: raise Gem::InvalidSpecificationException, "#{field} may not be empty" if 2036: val.empty? 2037: end 2038: 2039: licenses.each { |license| 2040: if license.length > 64 2041: raise Gem::InvalidSpecificationException, 2042: "each license must be 64 characters or less" 2043: end 2044: } 2045: 2046: # reject lazy developers: 2047: 2048: lazy = '"FIxxxXME" or "TOxxxDO"'.gsub(/xxx/, '') 2049: 2050: unless authors.grep(/FI XME|TO DO/x).empty? then 2051: raise Gem::InvalidSpecificationException, "#{lazy} is not an author" 2052: end 2053: 2054: unless Array(email).grep(/FI XME|TO DO/x).empty? then 2055: raise Gem::InvalidSpecificationException, "#{lazy} is not an email" 2056: end 2057: 2058: if description =~ /FI XME|TO DO/x then 2059: raise Gem::InvalidSpecificationException, "#{lazy} is not a description" 2060: end 2061: 2062: if summary =~ /FI XME|TO DO/x then 2063: raise Gem::InvalidSpecificationException, "#{lazy} is not a summary" 2064: end 2065: 2066: if homepage and not homepage.empty? and 2067: homepage !~ /\A[a-z][a-z\d+.-]*:/i then 2068: raise Gem::InvalidSpecificationException, 2069: "\"#{homepage}\" is not a URI" 2070: end 2071: 2072: # Warnings 2073: 2074: %w[author description email homepage summary].each do |attribute| 2075: value = self.send attribute 2076: alert_warning "no #{attribute} specified" if value.nil? or value.empty? 2077: end 2078: 2079: if description == summary then 2080: alert_warning 'description and summary are identical' 2081: end 2082: 2083: # TODO: raise at some given date 2084: alert_warning "deprecated autorequire specified" if autorequire 2085: 2086: executables.each do |executable| 2087: executable_path = File.join(bindir, executable) 2088: shebang = File.read(executable_path, 2) == '#!' 2089: 2090: alert_warning "#{executable_path} is missing #! line" unless shebang 2091: end 2092: 2093: true 2094: end
Set the version to version, potentially also setting required_rubygems_version if version indicates it is a prerelease.
# File lib/rubygems/specification.rb, line 2101 2101: def version= version 2102: @version = Gem::Version.create(version) 2103: self.required_rubygems_version = '> 1.3.1' if @version.prerelease? 2104: return @version 2105: end