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 649 649: def self._load(str) 650: array = Marshal.load str 651: 652: spec = Gem::Specification.new 653: spec.instance_variable_set :@specification_version, array[1] 654: 655: current_version = CURRENT_SPECIFICATION_VERSION 656: 657: field_count = if spec.specification_version > current_version then 658: spec.instance_variable_set :@specification_version, 659: current_version 660: MARSHAL_FIELDS[current_version] 661: else 662: MARSHAL_FIELDS[spec.specification_version] 663: end 664: 665: if array.size < field_count then 666: raise TypeError, "invalid Gem::Specification format #{array.inspect}" 667: end 668: 669: # Cleanup any YAML::PrivateType. They only show up for an old bug 670: # where nil => null, so just convert them to nil based on the type. 671: 672: array.map! { |e| e.kind_of?(YAML::PrivateType) ? nil : e } 673: 674: spec.instance_variable_set :@rubygems_version, array[0] 675: # spec version 676: spec.instance_variable_set :@name, array[2] 677: spec.instance_variable_set :@version, array[3] 678: spec.date = array[4] 679: spec.instance_variable_set :@summary, array[5] 680: spec.instance_variable_set :@required_ruby_version, array[6] 681: spec.instance_variable_set :@required_rubygems_version, array[7] 682: spec.instance_variable_set :@original_platform, array[8] 683: spec.instance_variable_set :@dependencies, array[9] 684: spec.instance_variable_set :@rubyforge_project, array[10] 685: spec.instance_variable_set :@email, array[11] 686: spec.instance_variable_set :@authors, array[12] 687: spec.instance_variable_set :@description, array[13] 688: spec.instance_variable_set :@homepage, array[14] 689: spec.instance_variable_set :@has_rdoc, array[15] 690: spec.instance_variable_set :@new_platform, array[16] 691: spec.instance_variable_set :@platform, array[16].to_s 692: spec.instance_variable_set :@license, array[17] 693: spec.instance_variable_set :@loaded, false 694: spec.instance_variable_set :@activated, false 695: 696: spec 697: end
Adds spec to the known specifications, keeping the collection properly sorted.
# File lib/rubygems/specification.rb, line 295 295: def self.add_spec spec 296: # TODO: find all extraneous adds 297: # puts 298: # p :add_spec => [spec.full_name, caller.reject { |s| s =~ /minitest/ }] 299: 300: # TODO: flush the rest of the crap from the tests 301: # raise "no dupes #{spec.full_name} in #{all_names.inspect}" if 302: # _all.include? spec 303: 304: raise "nil spec!" unless spec # TODO: remove once we're happy with tests 305: 306: return if _all.include? spec 307: 308: _all << spec 309: _resort! 310: end
Adds multiple specs to the known specifications.
# File lib/rubygems/specification.rb, line 315 315: def self.add_specs *specs 316: raise "nil spec!" if specs.any?(&:nil?) # TODO: remove once we're happy 317: 318: # TODO: this is much more efficient, but we need the extra checks for now 319: # _all.concat specs 320: # _resort! 321: 322: specs.each do |spec| # TODO: slow 323: add_spec spec 324: end 325: 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 331 331: def self.all 332: warn "NOTE: Specification.all called from #{caller.first}" unless 333: Gem::Deprecate.skip 334: _all 335: 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 349 349: def self.all= specs 350: @@all = specs 351: end
Return the directories that Specification uses to find specs.
# File lib/rubygems/specification.rb, line 381 381: def self.dirs 382: @@dirs ||= Gem.path.collect { |dir| 383: File.join dir, "specifications" 384: } 385: end
Set the directories that Specification uses to find specs. Setting this resets the list of known specs.
# File lib/rubygems/specification.rb, line 391 391: def self.dirs= dirs 392: # TODO: find extra calls to dir= 393: # warn "NOTE: dirs= called from #{caller.first} for #{dirs.inspect}" 394: 395: self.reset 396: 397: # ugh 398: @@dirs = Array(dirs).map { |dir| File.join dir, "specifications" } 399: end
Returns every spec that matches name and optional requirements.
# File lib/rubygems/specification.rb, line 418 418: def self.find_all_by_name name, *requirements 419: requirements = Gem::Requirement.default if requirements.empty? 420: 421: # TODO: maybe try: find_all { |s| spec === dep } 422: 423: Gem::Dependency.new(name, *requirements).matching_specs 424: 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 430 430: def self.find_by_name name, *requirements 431: requirements = Gem::Requirement.default if requirements.empty? 432: 433: # TODO: maybe try: find { |s| spec === dep } 434: 435: Gem::Dependency.new(name, *requirements).to_spec 436: end
Return the best specification that contains the file matching path.
# File lib/rubygems/specification.rb, line 441 441: def self.find_by_path path 442: self.find { |spec| 443: spec.contains_requirable_file? path 444: } 445: end
Return currently unresolved specs that contain the file matching path.
# File lib/rubygems/specification.rb, line 450 450: def self.find_in_unresolved path 451: # TODO: do we need these?? Kill it 452: specs = Gem.unresolved_deps.values.map { |dep| dep.to_specs }.flatten 453: 454: specs.find_all { |spec| spec.contains_requirable_file? path } 455: end
Search through all unresolved deps and sub-dependencies and return specs that contain the file matching path.
# File lib/rubygems/specification.rb, line 461 461: def self.find_in_unresolved_tree path 462: specs = Gem.unresolved_deps.values.map { |dep| dep.to_specs }.flatten 463: 464: specs.reverse_each do |spec| 465: trails = [] 466: spec.traverse do |from_spec, dep, to_spec, trail| 467: next unless to_spec.conflicts.empty? 468: trails << trail if to_spec.contains_requirable_file? path 469: end 470: 471: next if trails.empty? 472: 473: return trails.map(&:reverse).sort.first.reverse 474: end 475: 476: [] 477: 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 487 487: def self.from_yaml(input) 488: Gem.load_yaml 489: 490: input = normalize_yaml_input input 491: spec = YAML.load input 492: 493: if spec && spec.class == FalseClass then 494: raise Gem::EndOfYAMLException 495: end 496: 497: unless Gem::Specification === spec then 498: raise Gem::Exception, "YAML data doesn't evaluate to gem specification" 499: end 500: 501: unless (spec.instance_variables.include? '@specification_version' or 502: spec.instance_variables.include? :@specification_version) and 503: spec.instance_variable_get :@specification_version 504: spec.instance_variable_set :@specification_version, 505: NONEXISTENT_SPECIFICATION_VERSION 506: end 507: 508: spec 509: end
Return the latest specs, optionally including prerelease specs if prerelease is true.
# File lib/rubygems/specification.rb, line 515 515: def self.latest_specs prerelease = false 516: result = Hash.new { |h,k| h[k] = {} } 517: native = {} 518: 519: Gem::Specification._all.reverse_each do |spec| 520: next if spec.version.prerelease? unless prerelease 521: 522: native[spec.name] = spec.version if spec.platform == Gem::Platform::RUBY 523: result[spec.name][spec.platform] = spec 524: end 525: 526: result.map(&:last).map(&:values).flatten.reject { |spec| 527: minimum = native[spec.name] 528: minimum && spec.version < minimum 529: } 530: end
Loads Ruby format gemspec from file.
# File lib/rubygems/specification.rb, line 535 535: def self.load file 536: return unless file && File.file?(file) 537: 538: file = file.dup.untaint 539: 540: code = if defined? Encoding 541: File.read file, :mode => 'r:UTF-8:-' 542: else 543: File.read file 544: end 545: 546: code.untaint 547: 548: begin 549: spec = eval code, binding, file 550: 551: if Gem::Specification === spec 552: spec.loaded_from = file.to_s 553: return spec 554: end 555: 556: warn "[#{file}] isn't a Gem::Specification (#{spec.class} instead)." 557: rescue SignalException, SystemExit 558: raise 559: rescue SyntaxError, Exception => e 560: warn "Invalid gemspec in [#{file}]: #{e}" 561: end 562: 563: nil 564: 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 1343 1343: def initialize name = nil, version = nil 1344: @loaded = false 1345: @activated = false 1346: @loaded_from = nil 1347: @original_platform = nil 1348: 1349: @@nil_attributes.each do |key| 1350: instance_variable_set "@#{key}", nil 1351: end 1352: 1353: @@non_nil_attributes.each do |key| 1354: default = default_value(key) 1355: value = case default 1356: when Time, Numeric, Symbol, true, false, nil then default 1357: else default.dup 1358: end 1359: 1360: instance_variable_set "@#{key}", value 1361: end 1362: 1363: @new_platform = Gem::Platform::RUBY 1364: 1365: self.name = name if name 1366: self.version = version if version 1367: 1368: yield self if block_given? 1369: end
Specification attributes that must be non-nil
# File lib/rubygems/specification.rb, line 569 569: def self.non_nil_attributes 570: @@non_nil_attributes.dup 571: end
Make sure the YAML specification is properly formatted with dashes
# File lib/rubygems/specification.rb, line 576 576: def self.normalize_yaml_input(input) 577: result = input.respond_to?(:read) ? input.read : input 578: result = "--- " + result unless result =~ /\A--- / 579: result.gsub!(/ !!null \n/, " \n") 580: # date: 2011-04-26 00:00:00.000000000Z 581: # date: 2011-04-26 00:00:00.000000000 Z 582: result.gsub!(/^(date: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+?)Z/, '\1 Z') 583: result 584: 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 590 590: def self.outdated 591: outdateds = [] 592: 593: # TODO: maybe we should switch to rubygems' version service? 594: fetcher = Gem::SpecFetcher.fetcher 595: 596: latest_specs.each do |local| 597: dependency = Gem::Dependency.new local.name, ">= #{local.version}" 598: remotes = fetcher.find_matching dependency 599: remotes = remotes.map { |(_, version, _), _| version } 600: latest = remotes.sort.last 601: 602: outdateds << local.name if latest and local.version < latest 603: end 604: 605: outdateds 606: end
Removes spec from the known specs.
# File lib/rubygems/specification.rb, line 611 611: def self.remove_spec spec 612: # TODO: beat on the tests 613: raise "wtf: #{spec.full_name} not in #{all_names.inspect}" unless 614: _all.include? spec 615: _all.delete spec 616: end
Is name a required attribute?
# File lib/rubygems/specification.rb, line 621 621: def self.required_attribute?(name) 622: @@required_attributes.include? name.to_sym 623: end
Required specification attributes
# File lib/rubygems/specification.rb, line 628 628: def self.required_attributes 629: @@required_attributes.dup 630: end
Reset the list of known specs, running pre and post reset hooks registered in Gem.
# File lib/rubygems/specification.rb, line 636 636: def self.reset 637: @@dirs = nil 638: # from = caller.first(10).reject { |s| s =~ /minitest/ } 639: # warn "" 640: # warn "NOTE: Specification.reset from #{from.inspect}" 641: Gem.pre_reset_hooks.each { |hook| hook.call } 642: @@all = nil 643: Gem.post_reset_hooks.each { |hook| hook.call } 644: end
Dump only crucial instance variables.
# File lib/rubygems/specification.rb, line 716 716: def _dump(limit) 717: Marshal.dump [ 718: @rubygems_version, 719: @specification_version, 720: @name, 721: @version, 722: date, 723: @summary, 724: @required_ruby_version, 725: @required_rubygems_version, 726: @original_platform, 727: @dependencies, 728: @rubyforge_project, 729: @email, 730: @authors, 731: @description, 732: @homepage, 733: true, # has_rdoc 734: @new_platform, 735: @licenses 736: ] 737: 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 745 745: def activate 746: raise_if_conflicts 747: 748: return false if Gem.loaded_specs[self.name] 749: 750: activate_dependencies 751: add_self_to_load_path 752: 753: Gem.loaded_specs[self.name] = self 754: @activated = true 755: @loaded = true 756: 757: return true 758: 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 765 765: def activate_dependencies 766: self.runtime_dependencies.each do |spec_dep| 767: if loaded = Gem.loaded_specs[spec_dep.name] 768: next if spec_dep.matches_spec? loaded 769: 770: msg = "can't satisfy '#{spec_dep}', already activated '#{loaded.full_name}'" 771: e = Gem::LoadError.new msg 772: e.name = spec_dep.name 773: 774: raise e 775: end 776: 777: specs = spec_dep.to_specs 778: 779: if specs.size == 1 then 780: specs.first.activate 781: else 782: name = spec_dep.name 783: Gem.unresolved_deps[name] = Gem.unresolved_deps[name].merge spec_dep 784: end 785: end 786: 787: Gem.unresolved_deps.delete self.name 788: end
Returns an array with bindir attached to each executable in the executables list
# File lib/rubygems/specification.rb, line 794 794: def add_bindir(executables) 795: return nil if executables.nil? 796: 797: if @bindir then 798: Array(executables).map { |e| File.join(@bindir, e) } 799: else 800: executables 801: end 802: rescue 803: return nil 804: 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 838 838: def add_development_dependency(gem, *requirements) 839: add_dependency_with_type(gem, :development, *requirements) 840: 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 848 848: def add_runtime_dependency(gem, *requirements) 849: add_dependency_with_type(gem, :runtime, *requirements) 850: end
Adds this spec‘s require paths to LOAD_PATH, in the proper location.
# File lib/rubygems/specification.rb, line 857 857: def add_self_to_load_path 858: paths = require_paths.map do |path| 859: File.join full_gem_path, path 860: end 861: 862: # gem directories must come after -I and ENV['RUBYLIB'] 863: insert_index = Gem.load_path_insert_index 864: 865: if insert_index then 866: # gem directories must come after -I and ENV['RUBYLIB'] 867: $LOAD_PATH.insert(insert_index, *paths) 868: else 869: # we are probably testing in core, -I and RUBYLIB don't apply 870: $LOAD_PATH.unshift(*paths) 871: end 872: 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 898 898: def authors 899: @authors ||= [] 900: end
Returns the full path to the base gem directory.
eg: /usr/local/lib/ruby/gems/1.8
# File lib/rubygems/specification.rb, line 914 914: def base_dir 915: return Gem.dir unless loaded_from 916: @base_dir ||= File.dirname File.dirname loaded_from 917: 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 925 925: def bin_dir 926: @bin_dir ||= File.join gem_dir, bindir # TODO: this is unfortunate 927: end
Returns the full path to an executable named name in this gem.
# File lib/rubygems/specification.rb, line 932 932: def bin_file name 933: File.join bin_dir, name 934: end
Returns the full path to the cache directory containing this spec‘s cached gem.
# File lib/rubygems/specification.rb, line 940 940: def cache_dir 941: @cache_dir ||= File.join base_dir, "cache" 942: end
Returns the full path to the cached gem for this spec.
# File lib/rubygems/specification.rb, line 947 947: def cache_file 948: @cache_file ||= File.join cache_dir, "#{full_name}.gem" 949: end
Return any possible conflicts against the currently loaded specs.
# File lib/rubygems/specification.rb, line 956 956: def conflicts 957: conflicts = {} 958: Gem.loaded_specs.values.each do |spec| 959: bad = self.runtime_dependencies.find_all { |dep| 960: spec.name == dep.name and not spec.satisfies_requirement? dep 961: } 962: 963: conflicts[spec] = bad unless bad.empty? 964: end 965: conflicts 966: end
Return true if this spec can require file.
# File lib/rubygems/specification.rb, line 971 971: def contains_requirable_file? file 972: root = full_gem_path 973: 974: require_paths.each do |lib| 975: base = "#{root}/#{lib}/#{file}" 976: Gem.suffixes.each do |suf| 977: path = "#{base}#{suf}" 978: return true if File.file? path 979: end 980: end 981: 982: return false 983: 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 997 997: def date= date 998: # We want to end up with a Time object with one-day resolution. 999: # This is the cleanest, most-readable, faster-than-using-Date 1000: # way to do it. 1001: @date = case date 1002: when String then 1003: if /\A(\d{4})-(\d{2})-(\d{2})\Z/ =~ date then 1004: Time.utc($1.to_i, $2.to_i, $3.to_i) 1005: 1006: # Workaround for where the date format output from psych isn't 1007: # parsed as a Time object by syck and thus comes through as a 1008: # string. 1009: elsif /\A(\d{4})-(\d{2})-(\d{2}) \d{2}:\d{2}:\d{2}\.\d+?Z\z/ =~ date then 1010: Time.utc($1.to_i, $2.to_i, $3.to_i) 1011: else 1012: raise(Gem::InvalidSpecificationException, 1013: "invalid date format in specification: #{date.inspect}") 1014: end 1015: when Time, Date then 1016: Time.utc(date.year, date.month, date.day) 1017: else 1018: TODAY 1019: end 1020: 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 1028 1028: def default_executable 1029: if defined?(@default_executable) and @default_executable 1030: result = @default_executable 1031: elsif @executables and @executables.size == 1 1032: result = Array(@executables).first 1033: else 1034: result = nil 1035: end 1036: result 1037: end
The default value for specification attribute name
# File lib/rubygems/specification.rb, line 1042 1042: def default_value name 1043: @@default_value[name] 1044: 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 1052 1052: def dependencies 1053: @dependencies ||= [] 1054: 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 1062 1062: def dependent_gems 1063: out = [] 1064: Gem::Specification.each do |spec| 1065: spec.dependencies.each do |dep| 1066: if self.satisfies_requirement?(dep) then 1067: sats = [] 1068: find_all_satisfiers(dep) do |sat| 1069: sats << sat 1070: end 1071: out << [spec, dep, sats] 1072: end 1073: end 1074: end 1075: out 1076: end
Returns all specs that matches this spec‘s runtime dependencies.
# File lib/rubygems/specification.rb, line 1081 1081: def dependent_specs 1082: runtime_dependencies.map { |dep| dep.to_specs }.flatten 1083: end
A long description of this gem
# File lib/rubygems/specification.rb, line 1088 1088: def description= str 1089: @description = str.to_s 1090: end
List of dependencies that are used for development
# File lib/rubygems/specification.rb, line 1095 1095: def development_dependencies 1096: dependencies.select { |d| d.type == :development } 1097: end
Returns the full path to this spec‘s documentation directory.
# File lib/rubygems/specification.rb, line 1102 1102: def doc_dir 1103: @doc_dir ||= File.join base_dir, 'doc', full_name 1104: end
Singular accessor for executables
# File lib/rubygems/specification.rb, line 1134 1134: def executable 1135: val = executables and val.first 1136: end
Singular accessor for executables
# File lib/rubygems/specification.rb, line 1141 1141: def executable=o 1142: self.executables = [o] 1143: end
Executables included in the gem.
# File lib/rubygems/specification.rb, line 1148 1148: def executables 1149: @executables ||= [] 1150: 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 1156 1156: def executables= value 1157: # TODO: warn about setting instead of pushing 1158: @executables = Array(value) 1159: end
Extensions to build when installing the gem. See Gem::Installer#build_extensions for valid values.
# File lib/rubygems/specification.rb, line 1165 1165: def extensions 1166: @extensions ||= [] 1167: 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 1173 1173: def extensions= extensions 1174: # TODO: warn about setting instead of pushing 1175: @extensions = Array extensions 1176: 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 1189 1189: def extra_rdoc_files= files 1190: # TODO: warn about setting instead of pushing 1191: @extra_rdoc_files = Array files 1192: 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 1212 1212: def files 1213: # DO NOT CHANGE TO ||= ! This is not a normal accessor. (yes, it sucks) 1214: @files = [@files, 1215: @test_files, 1216: add_bindir(@executables), 1217: @extra_rdoc_files, 1218: @extensions, 1219: ].flatten.uniq.compact 1220: end
Creates a duplicate spec without large blobs that aren‘t used at runtime.
# File lib/rubygems/specification.rb, line 1243 1243: def for_cache 1244: spec = dup 1245: 1246: spec.files = nil 1247: spec.test_files = nil 1248: 1249: spec 1250: end
The full path to the gem (install path + full name).
# File lib/rubygems/specification.rb, line 1255 1255: def full_gem_path 1256: # TODO: try to get rid of this... or the awkward 1257: # TODO: also, shouldn't it default to full_name if it hasn't been written? 1258: return @full_gem_path if defined?(@full_gem_path) && @full_gem_path 1259: 1260: @full_gem_path = File.expand_path File.join(gems_dir, full_name) 1261: 1262: return @full_gem_path if File.directory? @full_gem_path 1263: 1264: @full_gem_path = File.expand_path File.join(gems_dir, original_name) 1265: 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 1272 1272: def full_name 1273: if platform == Gem::Platform::RUBY or platform.nil? then 1274: "#{@name}-#{@version}" 1275: else 1276: "#{@name}-#{@version}-#{platform}" 1277: end 1278: 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 1284 1284: def gem_dir 1285: @gem_dir ||= File.expand_path File.join(gems_dir, full_name) 1286: 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 1292 1292: def gems_dir 1293: # TODO: this logic seems terribly broken, but tests fail if just base_dir 1294: @gems_dir ||= File.join(loaded_from && base_dir || Gem.dir, "gems") 1295: end
Deprecated and ignored, defaults to true.
Formerly used to indicate this gem was RDoc-capable.
# File lib/rubygems/specification.rb, line 1302 1302: def has_rdoc 1303: true 1304: end
Deprecated and ignored.
Formerly used to indicate this gem was RDoc-capable.
# File lib/rubygems/specification.rb, line 1311 1311: def has_rdoc= ignored 1312: @has_rdoc = true 1313: end
True if this gem has files in test_files
# File lib/rubygems/specification.rb, line 1320 1320: def has_unit_tests? 1321: not test_files.empty? 1322: end
Duplicates array_attributes from other_spec so state isn‘t shared.
# File lib/rubygems/specification.rb, line 1374 1374: def initialize_copy other_spec 1375: other_ivars = other_spec.instance_variables 1376: other_ivars = other_ivars.map { |ivar| ivar.intern } if # for 1.9 1377: String === other_ivars.first 1378: 1379: self.class.array_attributes.each do |name| 1380: name = "@#{name}""@#{name}" 1381: next unless other_ivars.include? name 1382: 1383: begin 1384: val = other_spec.instance_variable_get(name) 1385: if val then 1386: instance_variable_set name, val.dup 1387: elsif Gem.configuration.really_verbose 1388: warn "WARNING: #{full_name} has an invalid nil value for #{name}" 1389: end 1390: rescue TypeError 1391: e = Gem::FormatException.new \ 1392: "#{full_name} has an invalid value for #{name}" 1393: 1394: e.file_path = loaded_from 1395: raise e 1396: end 1397: end 1398: end
Returns a string usable in Dir.glob to match all requirable paths for this spec.
# File lib/rubygems/specification.rb, line 1412 1412: def lib_dirs_glob 1413: dirs = if self.require_paths.size > 1 then 1414: "{#{self.require_paths.join(',')}}" 1415: else 1416: self.require_paths.first 1417: end 1418: 1419: "#{self.full_gem_path}/#{dirs}" 1420: end
Set the location a Specification was loaded from. obj is converted to a String.
# File lib/rubygems/specification.rb, line 1466 1466: def loaded_from= path 1467: @loaded_from = path.to_s 1468: end
Sets the rubygems_version to the current RubyGems version.
# File lib/rubygems/specification.rb, line 1473 1473: def mark_version 1474: @rubygems_version = Gem::VERSION 1475: end
Return all files in this gem that match for glob.
# File lib/rubygems/specification.rb, line 1480 1480: def matches_for_glob glob # TODO: rename? 1481: # TODO: do we need these?? Kill it 1482: glob = File.join(self.lib_dirs_glob, glob) 1483: 1484: Dir[glob].map { |f| f.untaint } # FIX our tests are broken, run w/ SAFE=1 1485: end
Normalize the list of files so that:
# File lib/rubygems/specification.rb, line 1505 1505: def normalize 1506: if defined?(@extra_rdoc_files) and @extra_rdoc_files then 1507: @extra_rdoc_files.uniq! 1508: @files ||= [] 1509: @files.concat(@extra_rdoc_files) 1510: end 1511: 1512: @files = @files.uniq if @files 1513: @extensions = @extensions.uniq if @extensions 1514: @test_files = @test_files.uniq if @test_files 1515: @executables = @executables.uniq if @executables 1516: @extra_rdoc_files = @extra_rdoc_files.uniq if @extra_rdoc_files 1517: end
The platform this gem runs on. See Gem::Platform for details.
# File lib/rubygems/specification.rb, line 1541 1541: def platform 1542: @new_platform ||= Gem::Platform::RUBY 1543: 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 1551 1551: def platform= platform 1552: if @original_platform.nil? or 1553: @original_platform == Gem::Platform::RUBY then 1554: @original_platform = platform 1555: end 1556: 1557: case platform 1558: when Gem::Platform::CURRENT then 1559: @new_platform = Gem::Platform.local 1560: @original_platform = @new_platform.to_s 1561: 1562: when Gem::Platform then 1563: @new_platform = platform 1564: 1565: # legacy constants 1566: when nil, Gem::Platform::RUBY then 1567: @new_platform = Gem::Platform::RUBY 1568: when 'mswin32' then # was Gem::Platform::WIN32 1569: @new_platform = Gem::Platform.new 'x86-mswin32' 1570: when 'i586-linux' then # was Gem::Platform::LINUX_586 1571: @new_platform = Gem::Platform.new 'x86-linux' 1572: when 'powerpc-darwin' then # was Gem::Platform::DARWIN 1573: @new_platform = Gem::Platform.new 'ppc-darwin' 1574: else 1575: @new_platform = Gem::Platform.new platform 1576: end 1577: 1578: @platform = @new_platform.to_s 1579: 1580: @new_platform 1581: end
Check the spec for possible conflicts and freak out if there are any.
# File lib/rubygems/specification.rb, line 1612 1612: def raise_if_conflicts 1613: other = Gem.loaded_specs[self.name] 1614: 1615: if other and self.version != other.version then 1616: # This gem is already loaded. If the currently loaded gem is not in the 1617: # list of candidate gems, then we have a version conflict. 1618: 1619: msg = "can't activate #{full_name}, already activated #{other.full_name}" 1620: 1621: e = Gem::LoadError.new msg 1622: e.name = self.name 1623: # TODO: e.requirement = dep.requirement 1624: 1625: raise e 1626: end 1627: 1628: conf = self.conflicts 1629: 1630: unless conf.empty? then 1631: y = conf.map { |act,con| 1632: "#{act.full_name} conflicts with #{con.join(", ")}" 1633: }.join ", " 1634: 1635: # TODO: improve message by saying who activated `con` 1636: 1637: raise Gem::LoadError, "Unable to activate #{self.full_name}, because #{y}" 1638: end 1639: end
An ARGV style array of options to RDoc
# File lib/rubygems/specification.rb, line 1644 1644: def rdoc_options 1645: @rdoc_options ||= [] 1646: 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 1652 1652: def rdoc_options= options 1653: # TODO: warn about setting instead of pushing 1654: @rdoc_options = Array options 1655: end
Singular accessor for require_paths
# File lib/rubygems/specification.rb, line 1660 1660: def require_path 1661: val = require_paths and val.first 1662: end
Singular accessor for require_paths
# File lib/rubygems/specification.rb, line 1667 1667: def require_path= path 1668: self.require_paths = [path] 1669: end
The version of ruby required by this gem
# File lib/rubygems/specification.rb, line 1674 1674: def required_ruby_version= req 1675: @required_ruby_version = Gem::Requirement.create req 1676: end
The RubyGems version required by this gem
# File lib/rubygems/specification.rb, line 1681 1681: def required_rubygems_version= req 1682: @required_rubygems_version = Gem::Requirement.create req 1683: end
An array or things required by this gem. Not used by anything presently.
# File lib/rubygems/specification.rb, line 1689 1689: def requirements 1690: @requirements ||= [] 1691: 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 1697 1697: def requirements= req 1698: # TODO: warn about setting instead of pushing 1699: @requirements = Array req 1700: end
Returns the full path to this spec‘s ri directory.
# File lib/rubygems/specification.rb, line 1705 1705: def ri_dir 1706: @ri_dir ||= File.join base_dir, 'ri', full_name 1707: end
List of dependencies that will automatically be activated at runtime.
# File lib/rubygems/specification.rb, line 1733 1733: def runtime_dependencies 1734: dependencies.select { |d| d.type == :runtime } 1735: end
Checks if this specification meets the requirement of dependency.
# File lib/rubygems/specification.rb, line 1749 1749: def satisfies_requirement? dependency 1750: return @name == dependency.name && 1751: dependency.requirement.satisfied_by?(@version) 1752: end
Returns an object you can use to sort specifications in sort_by.
# File lib/rubygems/specification.rb, line 1757 1757: def sort_obj 1758: # TODO: this is horrible. Deprecate it. 1759: [@name, @version, @new_platform == Gem::Platform::RUBY ? -1 : 1] 1760: 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 1766 1766: def spec_dir 1767: @spec_dir ||= File.join base_dir, "specifications" 1768: 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 1774 1774: def spec_file 1775: @spec_file ||= File.join spec_dir, "#{full_name}.gemspec" 1776: end
A short summary of this gem‘s description.
# File lib/rubygems/specification.rb, line 1790 1790: def summary= str 1791: @summary = str.to_s.strip. 1792: gsub(/(\w-)\n[ \t]*(\w)/, '\1\2').gsub(/\n[ \t]*/, " ") # so. weird. 1793: end
Singular accessor for test_files
# File lib/rubygems/specification.rb, line 1798 1798: def test_file 1799: val = test_files and val.first 1800: end
Singular accessor for test_files
# File lib/rubygems/specification.rb, line 1805 1805: def test_file= file 1806: self.test_files = [file] 1807: end
Test files included in this gem. You cannot append to this accessor, you must assign to it.
# File lib/rubygems/specification.rb, line 1813 1813: def test_files 1814: # Handle the possibility that we have @test_suite_file but not 1815: # @test_files. This will happen when an old gem is loaded via 1816: # YAML. 1817: if defined? @test_suite_file then 1818: @test_files = [@test_suite_file].flatten 1819: @test_suite_file = nil 1820: end 1821: if defined?(@test_files) and @test_files then 1822: @test_files 1823: else 1824: @test_files = [] 1825: end 1826: end
Set test_files to files, ensuring it is an array.
# File lib/rubygems/specification.rb, line 1831 1831: def test_files= files 1832: @test_files = Array files 1833: 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 1851 1851: def to_ruby 1852: mark_version 1853: result = [] 1854: result << "# -*- encoding: utf-8 -*-" 1855: result << nil 1856: result << "Gem::Specification.new do |s|" 1857: 1858: result << " s.name = #{ruby_code name}" 1859: result << " s.version = #{ruby_code version}" 1860: unless platform.nil? or platform == Gem::Platform::RUBY then 1861: result << " s.platform = #{ruby_code original_platform}" 1862: end 1863: result << "" 1864: result << " s.required_rubygems_version = #{ruby_code required_rubygems_version} if s.respond_to? :required_rubygems_version=" 1865: 1866: handled = [ 1867: :dependencies, 1868: :name, 1869: :platform, 1870: :required_rubygems_version, 1871: :specification_version, 1872: :version, 1873: :has_rdoc, 1874: :default_executable, 1875: ] 1876: 1877: @@attributes.each do |attr_name| 1878: next if handled.include? attr_name 1879: current_value = self.send(attr_name) 1880: if current_value != default_value(attr_name) or 1881: self.class.required_attribute? attr_name then 1882: result << " s.#{attr_name} = #{ruby_code current_value}" 1883: end 1884: end 1885: 1886: result << nil 1887: result << " if s.respond_to? :specification_version then" 1888: result << " s.specification_version = #{specification_version}" 1889: result << nil 1890: 1891: result << " if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then" 1892: 1893: dependencies.each do |dep| 1894: req = dep.requirements_list.inspect 1895: dep.instance_variable_set :@type, :runtime if dep.type.nil? # HACK 1896: result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>, #{req})" 1897: end 1898: 1899: result << " else" 1900: 1901: dependencies.each do |dep| 1902: version_reqs_param = dep.requirements_list.inspect 1903: result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})" 1904: end 1905: 1906: result << ' end' 1907: 1908: result << " else" 1909: dependencies.each do |dep| 1910: version_reqs_param = dep.requirements_list.inspect 1911: result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})" 1912: end 1913: result << " end" 1914: 1915: result << "end" 1916: result << nil 1917: 1918: result.join "\n" 1919: end
Recursively walk dependencies of this spec, executing the block for each hop.
# File lib/rubygems/specification.rb, line 1966 1966: def traverse trail = [], &block 1967: trail = trail + [self] 1968: runtime_dependencies.each do |dep| 1969: dep.to_specs.each do |dep_spec| 1970: block[self, dep, dep_spec, trail + [dep_spec]] 1971: dep_spec.traverse(trail, &block) unless 1972: trail.map(&:name).include? dep_spec.name 1973: end 1974: end 1975: 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 1984 1984: def validate packaging = true 1985: require 'rubygems/user_interaction' 1986: extend Gem::UserInteraction 1987: normalize 1988: 1989: nil_attributes = self.class.non_nil_attributes.find_all do |name| 1990: instance_variable_get("@#{name}").nil? 1991: end 1992: 1993: unless nil_attributes.empty? then 1994: raise Gem::InvalidSpecificationException, 1995: "#{nil_attributes.join ', '} must not be nil" 1996: end 1997: 1998: if packaging and rubygems_version != Gem::VERSION then 1999: raise Gem::InvalidSpecificationException, 2000: "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}" 2001: end 2002: 2003: @@required_attributes.each do |symbol| 2004: unless self.send symbol then 2005: raise Gem::InvalidSpecificationException, 2006: "missing value for attribute #{symbol}" 2007: end 2008: end 2009: 2010: unless String === name then 2011: raise Gem::InvalidSpecificationException, 2012: "invalid value for attribute name: \"#{name.inspect}\"" 2013: end 2014: 2015: if require_paths.empty? then 2016: raise Gem::InvalidSpecificationException, 2017: 'specification must have at least one require_path' 2018: end 2019: 2020: @files.delete_if { |x| File.directory?(x) } 2021: @test_files.delete_if { |x| File.directory?(x) } 2022: @executables.delete_if { |x| File.directory?(File.join(@bindir, x)) } 2023: @extra_rdoc_files.delete_if { |x| File.directory?(x) } 2024: @extensions.delete_if { |x| File.directory?(x) } 2025: 2026: non_files = files.reject { |x| File.file?(x) } 2027: 2028: unless not packaging or non_files.empty? then 2029: raise Gem::InvalidSpecificationException, 2030: "[\"#{non_files.join "\", \""}\"] are not files" 2031: end 2032: 2033: unless specification_version.is_a?(Fixnum) 2034: raise Gem::InvalidSpecificationException, 2035: 'specification_version must be a Fixnum (did you mean version?)' 2036: end 2037: 2038: case platform 2039: when Gem::Platform, Gem::Platform::RUBY then # ok 2040: else 2041: raise Gem::InvalidSpecificationException, 2042: "invalid platform #{platform.inspect}, see Gem::Platform" 2043: end 2044: 2045: self.class.array_attributes.each do |field| 2046: val = self.send field 2047: klass = case field 2048: when :dependencies 2049: Gem::Dependency 2050: else 2051: String 2052: end 2053: 2054: unless Array === val and val.all? { |x| x.kind_of?(klass) } then 2055: raise(Gem::InvalidSpecificationException, 2056: "#{field} must be an Array of #{klass}") 2057: end 2058: end 2059: 2060: [:authors].each do |field| 2061: val = self.send field 2062: raise Gem::InvalidSpecificationException, "#{field} may not be empty" if 2063: val.empty? 2064: end 2065: 2066: licenses.each { |license| 2067: if license.length > 64 2068: raise Gem::InvalidSpecificationException, 2069: "each license must be 64 characters or less" 2070: end 2071: } 2072: 2073: # reject lazy developers: 2074: 2075: lazy = '"FIxxxXME" or "TOxxxDO"'.gsub(/xxx/, '') 2076: 2077: unless authors.grep(/FI XME|TO DO/x).empty? then 2078: raise Gem::InvalidSpecificationException, "#{lazy} is not an author" 2079: end 2080: 2081: unless Array(email).grep(/FI XME|TO DO/x).empty? then 2082: raise Gem::InvalidSpecificationException, "#{lazy} is not an email" 2083: end 2084: 2085: if description =~ /FI XME|TO DO/x then 2086: raise Gem::InvalidSpecificationException, "#{lazy} is not a description" 2087: end 2088: 2089: if summary =~ /FI XME|TO DO/x then 2090: raise Gem::InvalidSpecificationException, "#{lazy} is not a summary" 2091: end 2092: 2093: if homepage and not homepage.empty? and 2094: homepage !~ /\A[a-z][a-z\d+.-]*:/i then 2095: raise Gem::InvalidSpecificationException, 2096: "\"#{homepage}\" is not a URI" 2097: end 2098: 2099: # Warnings 2100: 2101: %w[author description email homepage summary].each do |attribute| 2102: value = self.send attribute 2103: alert_warning "no #{attribute} specified" if value.nil? or value.empty? 2104: end 2105: 2106: if description == summary then 2107: alert_warning 'description and summary are identical' 2108: end 2109: 2110: # TODO: raise at some given date 2111: alert_warning "deprecated autorequire specified" if autorequire 2112: 2113: executables.each do |executable| 2114: executable_path = File.join(bindir, executable) 2115: shebang = File.read(executable_path, 2) == '#!' 2116: 2117: alert_warning "#{executable_path} is missing #! line" unless shebang 2118: end 2119: 2120: true 2121: 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 2128 2128: def version= version 2129: @version = Gem::Version.create(version) 2130: self.required_rubygems_version = '> 1.3.1' if @version.prerelease? 2131: return @version 2132: end