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.
The the version number of a specification that does not specify one (i.e. RubyGems 0.7 or earlier).
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
Paths in the gem to add to $LOAD_PATH when this gem is activated.
The default [‘lib’] is typically sufficient.
The version of RubyGems used to create this gem.
Do not set this, it is set automatically when the gem is packaged.
The Gem::Specification version of this gemspec.
Do not set this, it is set automatically when the gem is packaged.
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.
Autorequire was used by old RubyGems to automatically require a file.
Deprecated: It is neither supported nor functional.
Sets the default executable for this gem.
Deprecated: You must now specify the executable name to Gem.bin_path.
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.
The rubyforge project this gem lives under. i.e. RubyGems’ rubyforge_project is “rubygems”.
Load custom marshal format, re-initializing defaults as needed
# File lib/rubygems/specification.rb, line 646 646: def self._load(str) 647: array = Marshal.load str 648: 649: spec = Gem::Specification.new 650: spec.instance_variable_set :@specification_version, array[1] 651: 652: current_version = CURRENT_SPECIFICATION_VERSION 653: 654: field_count = if spec.specification_version > current_version then 655: spec.instance_variable_set :@specification_version, 656: current_version 657: MARSHAL_FIELDS[current_version] 658: else 659: MARSHAL_FIELDS[spec.specification_version] 660: end 661: 662: if array.size < field_count then 663: raise TypeError, "invalid Gem::Specification format #{array.inspect}" 664: end 665: 666: spec.instance_variable_set :@rubygems_version, array[0] 667: # spec version 668: spec.instance_variable_set :@name, array[2] 669: spec.instance_variable_set :@version, array[3] 670: spec.instance_variable_set :@date, array[4] 671: spec.instance_variable_set :@summary, array[5] 672: spec.instance_variable_set :@required_ruby_version, array[6] 673: spec.instance_variable_set :@required_rubygems_version, array[7] 674: spec.instance_variable_set :@original_platform, array[8] 675: spec.instance_variable_set :@dependencies, array[9] 676: spec.instance_variable_set :@rubyforge_project, array[10] 677: spec.instance_variable_set :@email, array[11] 678: spec.instance_variable_set :@authors, array[12] 679: spec.instance_variable_set :@description, array[13] 680: spec.instance_variable_set :@homepage, array[14] 681: spec.instance_variable_set :@has_rdoc, array[15] 682: spec.instance_variable_set :@new_platform, array[16] 683: spec.instance_variable_set :@platform, array[16].to_s 684: spec.instance_variable_set :@license, array[17] 685: spec.instance_variable_set :@loaded, false 686: spec.instance_variable_set :@activated, false 687: 688: spec 689: 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 full names of all specs in sorted order.
# File lib/rubygems/specification.rb, line 355 355: def self.all_names 356: self._all.map(&:full_name) 357: end
Return the list of all array-oriented instance variables.
# File lib/rubygems/specification.rb, line 364 364: def self.array_attributes 365: @@array_attributes.dup 366: end
Return the list of all instance variables.
# File lib/rubygems/specification.rb, line 373 373: def self.attribute_names 374: @@attributes.dup 375: 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
Enumerate every known spec. See ::dirs= and ::add_spec to set the list of specs.
# File lib/rubygems/specification.rb, line 406 406: def self.each 407: return enum_for(:each) unless block_given? 408: 409: self._all.each do |x| 410: yield x 411: end 412: 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 (#). 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: input = normalize_yaml_input input 488: spec = YAML.load input 489: 490: if spec && spec.class == FalseClass then 491: raise Gem::EndOfYAMLException 492: end 493: 494: unless Gem::Specification === spec then 495: raise Gem::Exception, "YAML data doesn't evaluate to gem specification" 496: end 497: 498: unless (spec.instance_variables.include? '@specification_version' or 499: spec.instance_variables.include? :@specification_version) and 500: spec.instance_variable_get :@specification_version 501: spec.instance_variable_set :@specification_version, 502: NONEXISTENT_SPECIFICATION_VERSION 503: end 504: 505: spec 506: end
Return the latest specs, optionally including prerelease specs if prerelease is true.
# File lib/rubygems/specification.rb, line 512 512: def self.latest_specs prerelease = false 513: result = Hash.new { |h,k| h[k] = {} } 514: native = {} 515: 516: Gem::Specification._all.reverse_each do |spec| 517: next if spec.version.prerelease? unless prerelease 518: 519: native[spec.name] = spec.version if spec.platform == Gem::Platform::RUBY 520: result[spec.name][spec.platform] = spec 521: end 522: 523: result.map(&:last).map(&:values).flatten.reject { |spec| 524: minimum = native[spec.name] 525: minimum && spec.version < minimum 526: } 527: end
Loads Ruby format gemspec from file.
# File lib/rubygems/specification.rb, line 532 532: def self.load file 533: return unless file && File.file?(file) 534: 535: file = file.dup.untaint 536: 537: code = if defined? Encoding 538: File.read file, :encoding => "UTF-8" 539: else 540: File.read file 541: end 542: 543: code.untaint 544: 545: begin 546: spec = eval code, binding, file 547: 548: if Gem::Specification === spec 549: spec.loaded_from = file.to_s 550: return spec 551: end 552: 553: warn "[#{file}] isn't a Gem::Specification (#{spec.class} instead)." 554: rescue SignalException, SystemExit 555: raise 556: rescue SyntaxError, Exception => e 557: warn "Invalid gemspec in [#{file}]: #{e}" 558: end 559: 560: nil 561: 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 1321 1321: def initialize name = nil, version = nil 1322: @loaded = false 1323: @activated = false 1324: @loaded_from = nil 1325: @original_platform = nil 1326: 1327: @@nil_attributes.each do |key| 1328: instance_variable_set "@#{key}", nil 1329: end 1330: 1331: @@non_nil_attributes.each do |key| 1332: default = default_value(key) 1333: value = case default 1334: when Time, Numeric, Symbol, true, false, nil then default 1335: else default.dup 1336: end 1337: 1338: instance_variable_set "@#{key}", value 1339: end 1340: 1341: @new_platform = Gem::Platform::RUBY 1342: 1343: self.name = name if name 1344: self.version = version if version 1345: 1346: yield self if block_given? 1347: end
Specification attributes that must be non-nil
# File lib/rubygems/specification.rb, line 566 566: def self.non_nil_attributes 567: @@non_nil_attributes.dup 568: end
Make sure the YAML specification is properly formatted with dashes
# File lib/rubygems/specification.rb, line 573 573: def self.normalize_yaml_input(input) 574: result = input.respond_to?(:read) ? input.read : input 575: result = "--- " + result unless result =~ /\A--- / 576: result.gsub!(/ !!null \n/, " \n") 577: # date: 2011-04-26 00:00:00.000000000Z 578: # date: 2011-04-26 00:00:00.000000000 Z 579: result.gsub!(/^(date: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d+?)Z/, '\1 Z') 580: result 581: 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 587 587: def self.outdated 588: outdateds = [] 589: 590: # TODO: maybe we should switch to rubygems' version service? 591: fetcher = Gem::SpecFetcher.fetcher 592: 593: latest_specs.each do |local| 594: dependency = Gem::Dependency.new local.name, ">= #{local.version}" 595: remotes = fetcher.find_matching dependency 596: remotes = remotes.map { |(_, version, _), _| version } 597: latest = remotes.sort.last 598: 599: outdateds << local.name if latest and local.version < latest 600: end 601: 602: outdateds 603: end
Removes spec from the known specs.
# File lib/rubygems/specification.rb, line 608 608: def self.remove_spec spec 609: # TODO: beat on the tests 610: raise "wtf: #{spec.full_name} not in #{all_names.inspect}" unless 611: _all.include? spec 612: _all.delete spec 613: end
Is name a required attribute?
# File lib/rubygems/specification.rb, line 618 618: def self.required_attribute?(name) 619: @@required_attributes.include? name.to_sym 620: end
Required specification attributes
# File lib/rubygems/specification.rb, line 625 625: def self.required_attributes 626: @@required_attributes.dup 627: end
Reset the list of known specs, running pre and post reset hooks registered in Gem.
# File lib/rubygems/specification.rb, line 633 633: def self.reset 634: @@dirs = nil 635: # from = caller.first(10).reject { |s| s =~ /minitest/ } 636: # warn "" 637: # warn "NOTE: Specification.reset from #{from.inspect}" 638: Gem.pre_reset_hooks.each { |hook| hook.call } 639: @@all = nil 640: Gem.post_reset_hooks.each { |hook| hook.call } 641: end
Dump only crucial instance variables.
# File lib/rubygems/specification.rb, line 708 708: def _dump(limit) 709: Marshal.dump [ 710: @rubygems_version, 711: @specification_version, 712: @name, 713: @version, 714: date, 715: @summary, 716: @required_ruby_version, 717: @required_rubygems_version, 718: @original_platform, 719: @dependencies, 720: @rubyforge_project, 721: @email, 722: @authors, 723: @description, 724: @homepage, 725: true, # has_rdoc 726: @new_platform, 727: @licenses 728: ] 729: 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 737 737: def activate 738: raise_if_conflicts 739: 740: return false if Gem.loaded_specs[self.name] 741: 742: activate_dependencies 743: add_self_to_load_path 744: 745: Gem.loaded_specs[self.name] = self 746: @activated = true 747: @loaded = true 748: 749: return true 750: 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 757 757: def activate_dependencies 758: self.runtime_dependencies.each do |spec_dep| 759: # TODO: check for conflicts! not just name! 760: next if Gem.loaded_specs.include? spec_dep.name 761: specs = spec_dep.to_specs 762: 763: if specs.size == 1 then 764: specs.first.activate 765: else 766: name = spec_dep.name 767: Gem.unresolved_deps[name] = Gem.unresolved_deps[name].merge spec_dep 768: end 769: end 770: 771: Gem.unresolved_deps.delete self.name 772: end
Returns an array with bindir attached to each executable in the executables list
# File lib/rubygems/specification.rb, line 778 778: def add_bindir(executables) 779: return nil if executables.nil? 780: 781: if @bindir then 782: Array(executables).map { |e| File.join(@bindir, e) } 783: else 784: executables 785: end 786: rescue 787: return nil 788: 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 822 822: def add_development_dependency(gem, *requirements) 823: add_dependency_with_type(gem, :development, *requirements) 824: 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 832 832: def add_runtime_dependency(gem, *requirements) 833: add_dependency_with_type(gem, :runtime, *requirements) 834: end
Adds this spec’s require paths to LOAD_PATH, in the proper location.
# File lib/rubygems/specification.rb, line 841 841: def add_self_to_load_path 842: paths = require_paths.map do |path| 843: File.join full_gem_path, path 844: end 845: 846: # gem directories must come after -I and ENV['RUBYLIB'] 847: insert_index = Gem.load_path_insert_index 848: 849: if insert_index then 850: # gem directories must come after -I and ENV['RUBYLIB'] 851: $LOAD_PATH.insert(insert_index, *paths) 852: else 853: # we are probably testing in core, -I and RUBYLIB don't apply 854: $LOAD_PATH.unshift(*paths) 855: end 856: end
Returns the full path to the base gem directory.
eg: /usr/local/lib/ruby/gems/1.8
# File lib/rubygems/specification.rb, line 898 898: def base_dir 899: return Gem.dir unless loaded_from 900: @base_dir ||= File.dirname File.dirname loaded_from 901: 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 909 909: def bin_dir 910: @bin_dir ||= File.join gem_dir, bindir # TODO: this is unfortunate 911: end
Returns the full path to an executable named name in this gem.
# File lib/rubygems/specification.rb, line 916 916: def bin_file name 917: File.join bin_dir, name 918: end
Returns the full path to the cache directory containing this spec’s cached gem.
# File lib/rubygems/specification.rb, line 924 924: def cache_dir 925: @cache_dir ||= File.join base_dir, "cache" 926: end
Returns the full path to the cached gem for this spec.
# File lib/rubygems/specification.rb, line 931 931: def cache_file 932: @cache_file ||= File.join cache_dir, "#{full_name}.gem" 933: end
Return any possible conflicts against the currently loaded specs.
# File lib/rubygems/specification.rb, line 940 940: def conflicts 941: conflicts = {} 942: Gem.loaded_specs.values.each do |spec| 943: bad = self.runtime_dependencies.find_all { |dep| 944: spec.name == dep.name and not spec.satisfies_requirement? dep 945: } 946: 947: conflicts[spec] = bad unless bad.empty? 948: end 949: conflicts 950: end
Return true if this spec can require file.
# File lib/rubygems/specification.rb, line 955 955: def contains_requirable_file? file 956: root = full_gem_path 957: 958: require_paths.each do |lib| 959: base = "#{root}/#{lib}/#{file}" 960: Gem.suffixes.each do |suf| 961: path = "#{base}#{suf}" 962: return true if File.file? path 963: end 964: end 965: 966: return false 967: end
The date this gem was created. Lazily defaults to TODAY.
# File lib/rubygems/specification.rb, line 972 972: def date 973: @date ||= TODAY 974: 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 981 981: def date= date 982: # We want to end up with a Time object with one-day resolution. 983: # This is the cleanest, most-readable, faster-than-using-Date 984: # way to do it. 985: @date = case date 986: when String then 987: if /\A(\d{4})-(\d{2})-(\d{2})\Z/ =~ date then 988: Time.utc($1.to_i, $2.to_i, $3.to_i) 989: else 990: raise(Gem::InvalidSpecificationException, 991: "invalid date format in specification: #{date.inspect}") 992: end 993: when Time, Date then 994: Time.utc(date.year, date.month, date.day) 995: else 996: TODAY 997: end 998: 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 1006 1006: def default_executable 1007: if defined?(@default_executable) and @default_executable 1008: result = @default_executable 1009: elsif @executables and @executables.size == 1 1010: result = Array(@executables).first 1011: else 1012: result = nil 1013: end 1014: result 1015: end
The default value for specification attribute name
# File lib/rubygems/specification.rb, line 1020 1020: def default_value name 1021: @@default_value[name] 1022: end
A list of Gem::Dependency objects this gem depends on.
Use # or # to add dependencies to a gem.
# File lib/rubygems/specification.rb, line 1030 1030: def dependencies 1031: @dependencies ||= [] 1032: 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 1040 1040: def dependent_gems 1041: out = [] 1042: Gem::Specification.each do |spec| 1043: spec.dependencies.each do |dep| 1044: if self.satisfies_requirement?(dep) then 1045: sats = [] 1046: find_all_satisfiers(dep) do |sat| 1047: sats << sat 1048: end 1049: out << [spec, dep, sats] 1050: end 1051: end 1052: end 1053: out 1054: end
Returns all specs that matches this spec’s runtime dependencies.
# File lib/rubygems/specification.rb, line 1059 1059: def dependent_specs 1060: runtime_dependencies.map { |dep| dep.to_specs }.flatten 1061: end
A long description of this gem
# File lib/rubygems/specification.rb, line 1066 1066: def description= str 1067: @description = str.to_s 1068: end
List of dependencies that are used for development
# File lib/rubygems/specification.rb, line 1073 1073: def development_dependencies 1074: dependencies.select { |d| d.type == :development } 1075: end
Returns the full path to this spec’s documentation directory.
# File lib/rubygems/specification.rb, line 1080 1080: def doc_dir 1081: @doc_dir ||= File.join base_dir, 'doc', full_name 1082: end
Singular accessor for #
# File lib/rubygems/specification.rb, line 1112 1112: def executable 1113: val = executables and val.first 1114: end
Singular accessor for #
# File lib/rubygems/specification.rb, line 1119 1119: def executable=o 1120: self.executables = [o] 1121: end
Executables included in the gem.
# File lib/rubygems/specification.rb, line 1126 1126: def executables 1127: @executables ||= [] 1128: 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 1134 1134: def executables= value 1135: # TODO: warn about setting instead of pushing 1136: @executables = Array(value) 1137: end
Extensions to build when installing the gem. See Gem::Installer#build_extensions for valid values.
# File lib/rubygems/specification.rb, line 1143 1143: def extensions 1144: @extensions ||= [] 1145: 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 1151 1151: def extensions= extensions 1152: # TODO: warn about setting instead of pushing 1153: @extensions = Array extensions 1154: end
Extra files to add to RDoc such as README or doc/examples.txt
# File lib/rubygems/specification.rb, line 1159 1159: def extra_rdoc_files 1160: @extra_rdoc_files ||= [] 1161: 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 1167 1167: def extra_rdoc_files= files 1168: # TODO: warn about setting instead of pushing 1169: @extra_rdoc_files = Array files 1170: end
The default (generated) file name of the gem. See also #.
spec.file_name # => "example-1.0.gem"
# File lib/rubygems/specification.rb, line 1177 1177: def file_name 1178: "#{full_name}.gem" 1179: 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 1190 1190: def files 1191: # DO NOT CHANGE TO ||= ! This is not a normal accessor. (yes, it sucks) 1192: @files = [@files, 1193: @test_files, 1194: add_bindir(@executables), 1195: @extra_rdoc_files, 1196: @extensions, 1197: ].flatten.uniq.compact 1198: end
Sets files to files, ensuring it is an array.
# File lib/rubygems/specification.rb, line 1203 1203: def files= files 1204: @files = Array files 1205: end
Creates a duplicate spec without large blobs that aren’t used at runtime.
# File lib/rubygems/specification.rb, line 1221 1221: def for_cache 1222: spec = dup 1223: 1224: spec.files = nil 1225: spec.test_files = nil 1226: 1227: spec 1228: end
The full path to the gem (install path + full name).
# File lib/rubygems/specification.rb, line 1233 1233: def full_gem_path 1234: # TODO: try to get rid of this... or the awkward 1235: # TODO: also, shouldn't it default to full_name if it hasn't been written? 1236: return @full_gem_path if defined?(@full_gem_path) && @full_gem_path 1237: 1238: @full_gem_path = File.expand_path File.join(gems_dir, full_name) 1239: 1240: return @full_gem_path if File.directory? @full_gem_path 1241: 1242: @full_gem_path = File.expand_path File.join(gems_dir, original_name) 1243: 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 1250 1250: def full_name 1251: if platform == Gem::Platform::RUBY or platform.nil? then 1252: "#{@name}-#{@version}" 1253: else 1254: "#{@name}-#{@version}-#{platform}" 1255: end 1256: 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 1262 1262: def gem_dir 1263: @gem_dir ||= File.expand_path File.join(gems_dir, full_name) 1264: 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 1270 1270: def gems_dir 1271: # TODO: this logic seems terribly broken, but tests fail if just base_dir 1272: @gems_dir ||= File.join(loaded_from && base_dir || Gem.dir, "gems") 1273: end
Deprecated and ignored, defaults to true.
Formerly used to indicate this gem was RDoc-capable.
# File lib/rubygems/specification.rb, line 1280 1280: def has_rdoc 1281: true 1282: end
Deprecated and ignored.
Formerly used to indicate this gem was RDoc-capable.
# File lib/rubygems/specification.rb, line 1289 1289: def has_rdoc= ignored 1290: @has_rdoc = true 1291: end
True if this gem has files in test_files
# File lib/rubygems/specification.rb, line 1298 1298: def has_unit_tests? 1299: not test_files.empty? 1300: end
Duplicates array_attributes from other_spec so state isn’t shared.
# File lib/rubygems/specification.rb, line 1352 1352: def initialize_copy other_spec 1353: other_ivars = other_spec.instance_variables 1354: other_ivars = other_ivars.map { |ivar| ivar.intern } if # for 1.9 1355: String === other_ivars.first 1356: 1357: self.class.array_attributes.each do |name| 1358: name = :"@#{name}" 1359: next unless other_ivars.include? name 1360: 1361: begin 1362: val = other_spec.instance_variable_get(name) 1363: if val then 1364: instance_variable_set name, val.dup 1365: else 1366: warn "WARNING: #{full_name} has an invalid nil value for #{name}" 1367: end 1368: rescue TypeError 1369: e = Gem::FormatException.new "#{full_name} has an invalid value for #{name}" 1370: 1371: e.file_path = loaded_from 1372: raise e 1373: end 1374: end 1375: end
The directory that this gem was installed into. TODO: rename - horrible. this is the base_dir for a gem path
# File lib/rubygems/specification.rb, line 1382 1382: def installation_path 1383: loaded_from && base_dir 1384: end
Returns a string usable in Dir.glob to match all requirable paths for this spec.
# File lib/rubygems/specification.rb, line 1390 1390: def lib_dirs_glob 1391: dirs = if self.require_paths.size > 1 then 1392: "{#{self.require_paths.join(',')}}" 1393: else 1394: self.require_paths.first 1395: end 1396: 1397: "#{self.full_gem_path}/#{dirs}" 1398: end
Files in the Gem under one of the require_paths
# File lib/rubygems/specification.rb, line 1403 1403: def lib_files 1404: @files.select do |file| 1405: require_paths.any? do |path| 1406: file.index(path) == 0 1407: end 1408: end 1409: end
Singular accessor for #
# File lib/rubygems/specification.rb, line 1414 1414: def license 1415: val = licenses and val.first 1416: end
Singular accessor for #
# File lib/rubygems/specification.rb, line 1421 1421: def license=o 1422: self.licenses = [o] 1423: end
The license(s) for the library. Each license must be a short name, no more than 64 characters.
# File lib/rubygems/specification.rb, line 1429 1429: def licenses 1430: @licenses ||= [] 1431: end
Set licenses to licenses, ensuring it is an array.
# File lib/rubygems/specification.rb, line 1436 1436: def licenses= licenses 1437: @licenses = Array licenses 1438: end
Set the location a Specification was loaded from. obj is converted to a String.
# File lib/rubygems/specification.rb, line 1444 1444: def loaded_from= path 1445: @loaded_from = path.to_s 1446: end
Sets the rubygems_version to the current RubyGems version.
# File lib/rubygems/specification.rb, line 1451 1451: def mark_version 1452: @rubygems_version = Gem::VERSION 1453: end
Return all files in this gem that match for glob.
# File lib/rubygems/specification.rb, line 1458 1458: def matches_for_glob glob # TODO: rename? 1459: # TODO: do we need these?? Kill it 1460: glob = File.join(self.lib_dirs_glob, glob) 1461: 1462: Dir[glob].map { |f| f.untaint } # FIX our tests are broken, run w/ SAFE=1 1463: end
Normalize the list of files so that:
All file lists have redundancies removed.
Files referenced in the extra_rdoc_files are included in the package file list.
# File lib/rubygems/specification.rb, line 1483 1483: def normalize 1484: if defined?(@extra_rdoc_files) and @extra_rdoc_files then 1485: @extra_rdoc_files.uniq! 1486: @files ||= [] 1487: @files.concat(@extra_rdoc_files) 1488: end 1489: 1490: @files = @files.uniq if @files 1491: @extensions = @extensions.uniq if @extensions 1492: @test_files = @test_files.uniq if @test_files 1493: @executables = @executables.uniq if @executables 1494: @extra_rdoc_files = @extra_rdoc_files.uniq if @extra_rdoc_files 1495: end
The platform this gem runs on. See Gem::Platform for details.
# File lib/rubygems/specification.rb, line 1519 1519: def platform 1520: @new_platform ||= Gem::Platform::RUBY 1521: 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 1529 1529: def platform= platform 1530: if @original_platform.nil? or 1531: @original_platform == Gem::Platform::RUBY then 1532: @original_platform = platform 1533: end 1534: 1535: case platform 1536: when Gem::Platform::CURRENT then 1537: @new_platform = Gem::Platform.local 1538: @original_platform = @new_platform.to_s 1539: 1540: when Gem::Platform then 1541: @new_platform = platform 1542: 1543: # legacy constants 1544: when nil, Gem::Platform::RUBY then 1545: @new_platform = Gem::Platform::RUBY 1546: when 'mswin32' then # was Gem::Platform::WIN32 1547: @new_platform = Gem::Platform.new 'x86-mswin32' 1548: when 'i586-linux' then # was Gem::Platform::LINUX_586 1549: @new_platform = Gem::Platform.new 'x86-linux' 1550: when 'powerpc-darwin' then # was Gem::Platform::DARWIN 1551: @new_platform = Gem::Platform.new 'ppc-darwin' 1552: else 1553: @new_platform = Gem::Platform.new platform 1554: end 1555: 1556: @platform = @new_platform.to_s 1557: 1558: @new_platform 1559: end
Check the spec for possible conflicts and freak out if there are any.
# File lib/rubygems/specification.rb, line 1590 1590: def raise_if_conflicts 1591: other = Gem.loaded_specs[self.name] 1592: 1593: if other and self.version != other.version then 1594: # This gem is already loaded. If the currently loaded gem is not in the 1595: # list of candidate gems, then we have a version conflict. 1596: 1597: msg = "can't activate #{full_name}, already activated #{other.full_name}" 1598: 1599: e = Gem::LoadError.new msg 1600: e.name = self.name 1601: # TODO: e.requirement = dep.requirement 1602: 1603: raise e 1604: end 1605: 1606: conf = self.conflicts 1607: 1608: unless conf.empty? then 1609: y = conf.map { |act,con| 1610: "#{act.full_name} conflicts with #{con.join(", ")}" 1611: }.join ", " 1612: 1613: # TODO: improve message by saying who activated `con` 1614: 1615: raise Gem::LoadError, "Unable to activate #{self.full_name}, because #{y}" 1616: end 1617: end
An ARGV style array of options to RDoc
# File lib/rubygems/specification.rb, line 1622 1622: def rdoc_options 1623: @rdoc_options ||= [] 1624: 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 1630 1630: def rdoc_options= options 1631: # TODO: warn about setting instead of pushing 1632: @rdoc_options = Array options 1633: end
Singular accessor for #
# File lib/rubygems/specification.rb, line 1638 1638: def require_path 1639: val = require_paths and val.first 1640: end
Singular accessor for #
# File lib/rubygems/specification.rb, line 1645 1645: def require_path= path 1646: self.require_paths = [path] 1647: end
The version of ruby required by this gem
# File lib/rubygems/specification.rb, line 1652 1652: def required_ruby_version= req 1653: @required_ruby_version = Gem::Requirement.create req 1654: end
The RubyGems version required by this gem
# File lib/rubygems/specification.rb, line 1659 1659: def required_rubygems_version= req 1660: @required_rubygems_version = Gem::Requirement.create req 1661: end
An array or things required by this gem. Not used by anything presently.
# File lib/rubygems/specification.rb, line 1667 1667: def requirements 1668: @requirements ||= [] 1669: 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 1675 1675: def requirements= req 1676: # TODO: warn about setting instead of pushing 1677: @requirements = Array req 1678: end
Returns the full path to this spec’s ri directory.
# File lib/rubygems/specification.rb, line 1683 1683: def ri_dir 1684: @ri_dir ||= File.join base_dir, 'ri', full_name 1685: end
List of dependencies that will automatically be activated at runtime.
# File lib/rubygems/specification.rb, line 1711 1711: def runtime_dependencies 1712: dependencies.select { |d| d.type == :runtime } 1713: end
Checks if this specification meets the requirement of dependency.
# File lib/rubygems/specification.rb, line 1727 1727: def satisfies_requirement? dependency 1728: return @name == dependency.name && 1729: dependency.requirement.satisfied_by?(@version) 1730: end
Returns an object you can use to sort specifications in #.
# File lib/rubygems/specification.rb, line 1735 1735: def sort_obj 1736: # TODO: this is horrible. Deprecate it. 1737: [@name, @version, @new_platform == Gem::Platform::RUBY ? 1 : 1] 1738: 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 1744 1744: def spec_dir 1745: @spec_dir ||= File.join base_dir, "specifications" 1746: 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 1752 1752: def spec_file 1753: @spec_file ||= File.join spec_dir, "#{full_name}.gemspec" 1754: end
The default name of the gemspec. See also #
spec.spec_name # => "example-1.0.gemspec"
# File lib/rubygems/specification.rb, line 1761 1761: def spec_name 1762: "#{full_name}.gemspec" 1763: end
A short summary of this gem’s description.
# File lib/rubygems/specification.rb, line 1768 1768: def summary= str 1769: @summary = str.to_s.strip. 1770: gsub(/(\w-)\n[ \t]*(\w)/, '\1\2').gsub(/\n[ \t]*/, " ") # so. weird. 1771: end
Singular accessor for #
# File lib/rubygems/specification.rb, line 1776 1776: def test_file 1777: val = test_files and val.first 1778: end
Singular accessor for #
# File lib/rubygems/specification.rb, line 1783 1783: def test_file= file 1784: self.test_files = [file] 1785: end
Test files included in this gem. You cannot append to this accessor, you must assign to it.
# File lib/rubygems/specification.rb, line 1791 1791: def test_files 1792: # Handle the possibility that we have @test_suite_file but not 1793: # @test_files. This will happen when an old gem is loaded via 1794: # YAML. 1795: if defined? @test_suite_file then 1796: @test_files = [@test_suite_file].flatten 1797: @test_suite_file = nil 1798: end 1799: if defined?(@test_files) and @test_files then 1800: @test_files 1801: else 1802: @test_files = [] 1803: end 1804: end
Set test_files to files, ensuring it is an array.
# File lib/rubygems/specification.rb, line 1809 1809: def test_files= files 1810: @test_files = Array files 1811: 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 1829 1829: def to_ruby 1830: mark_version 1831: result = [] 1832: result << "# -*- encoding: utf-8 -*-" 1833: result << nil 1834: result << "Gem::Specification.new do |s|" 1835: 1836: result << " s.name = #{ruby_code name}" 1837: result << " s.version = #{ruby_code version}" 1838: unless platform.nil? or platform == Gem::Platform::RUBY then 1839: result << " s.platform = #{ruby_code original_platform}" 1840: end 1841: result << "" 1842: result << " s.required_rubygems_version = #{ruby_code required_rubygems_version} if s.respond_to? :required_rubygems_version=" 1843: 1844: handled = [ 1845: :dependencies, 1846: :name, 1847: :platform, 1848: :required_rubygems_version, 1849: :specification_version, 1850: :version, 1851: :has_rdoc, 1852: :default_executable, 1853: ] 1854: 1855: @@attributes.each do |attr_name| 1856: next if handled.include? attr_name 1857: current_value = self.send(attr_name) 1858: if current_value != default_value(attr_name) or 1859: self.class.required_attribute? attr_name then 1860: result << " s.#{attr_name} = #{ruby_code current_value}" 1861: end 1862: end 1863: 1864: result << nil 1865: result << " if s.respond_to? :specification_version then" 1866: result << " s.specification_version = #{specification_version}" 1867: result << nil 1868: 1869: result << " if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then" 1870: 1871: dependencies.each do |dep| 1872: req = dep.requirements_list.inspect 1873: dep.instance_variable_set :@type, :runtime if dep.type.nil? # HACK 1874: result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>, #{req})" 1875: end 1876: 1877: result << " else" 1878: 1879: dependencies.each do |dep| 1880: version_reqs_param = dep.requirements_list.inspect 1881: result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})" 1882: end 1883: 1884: result << ' end' 1885: 1886: result << " else" 1887: dependencies.each do |dep| 1888: version_reqs_param = dep.requirements_list.inspect 1889: result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})" 1890: end 1891: result << " end" 1892: 1893: result << "end" 1894: result << nil 1895: 1896: result.join "\n" 1897: end
Returns a Ruby lighter-weight code representation of this specification, used for indexing only.
See #.
# File lib/rubygems/specification.rb, line 1905 1905: def to_ruby_for_cache 1906: for_cache.to_ruby 1907: end
Recursively walk dependencies of this spec, executing the block for each hop.
# File lib/rubygems/specification.rb, line 1929 1929: def traverse trail = [], &block 1930: trail = trail + [self] 1931: runtime_dependencies.each do |dep| 1932: dep.to_specs.each do |dep_spec| 1933: block[self, dep, dep_spec, trail + [dep_spec]] 1934: dep_spec.traverse(trail, &block) unless 1935: trail.map(&:name).include? dep_spec.name 1936: end 1937: end 1938: 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 1947 1947: def validate packaging = true 1948: require 'rubygems/user_interaction' 1949: extend Gem::UserInteraction 1950: normalize 1951: 1952: nil_attributes = self.class.non_nil_attributes.find_all do |name| 1953: instance_variable_get("@#{name}").nil? 1954: end 1955: 1956: unless nil_attributes.empty? then 1957: raise Gem::InvalidSpecificationException, 1958: "#{nil_attributes.join ', '} must not be nil" 1959: end 1960: 1961: if packaging and rubygems_version != Gem::VERSION then 1962: raise Gem::InvalidSpecificationException, 1963: "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}" 1964: end 1965: 1966: @@required_attributes.each do |symbol| 1967: unless self.send symbol then 1968: raise Gem::InvalidSpecificationException, 1969: "missing value for attribute #{symbol}" 1970: end 1971: end 1972: 1973: unless String === name then 1974: raise Gem::InvalidSpecificationException, 1975: "invalid value for attribute name: \"#{name.inspect}\"" 1976: end 1977: 1978: if require_paths.empty? then 1979: raise Gem::InvalidSpecificationException, 1980: 'specification must have at least one require_path' 1981: end 1982: 1983: @files.delete_if { |x| File.directory?(x) } 1984: @test_files.delete_if { |x| File.directory?(x) } 1985: @executables.delete_if { |x| File.directory?(File.join(@bindir, x)) } 1986: @extra_rdoc_files.delete_if { |x| File.directory?(x) } 1987: @extensions.delete_if { |x| File.directory?(x) } 1988: 1989: non_files = files.reject { |x| File.file?(x) } 1990: 1991: unless not packaging or non_files.empty? then 1992: raise Gem::InvalidSpecificationException, 1993: "[\"#{non_files.join "\", \""}\"] are not files" 1994: end 1995: 1996: unless specification_version.is_a?(Fixnum) 1997: raise Gem::InvalidSpecificationException, 1998: 'specification_version must be a Fixnum (did you mean version?)' 1999: end 2000: 2001: case platform 2002: when Gem::Platform, Gem::Platform::RUBY then # ok 2003: else 2004: raise Gem::InvalidSpecificationException, 2005: "invalid platform #{platform.inspect}, see Gem::Platform" 2006: end 2007: 2008: self.class.array_attributes.each do |field| 2009: val = self.send field 2010: klass = case field 2011: when :dependencies 2012: Gem::Dependency 2013: else 2014: String 2015: end 2016: 2017: unless Array === val and val.all? { |x| x.kind_of?(klass) } then 2018: raise(Gem::InvalidSpecificationException, 2019: "#{field} must be an Array of #{klass}") 2020: end 2021: end 2022: 2023: [:authors].each do |field| 2024: val = self.send field 2025: raise Gem::InvalidSpecificationException, "#{field} may not be empty" if 2026: val.empty? 2027: end 2028: 2029: licenses.each { |license| 2030: if license.length > 64 2031: raise Gem::InvalidSpecificationException, 2032: "each license must be 64 characters or less" 2033: end 2034: } 2035: 2036: # reject lazy developers: 2037: 2038: lazy = '"FIxxxXME" or "TOxxxDO"'.gsub(/xxx/, '') 2039: 2040: unless authors.grep(/FI XME|TO DO/).empty? then 2041: raise Gem::InvalidSpecificationException, "#{lazy} is not an author" 2042: end 2043: 2044: unless Array(email).grep(/FI XME|TO DO/).empty? then 2045: raise Gem::InvalidSpecificationException, "#{lazy} is not an email" 2046: end 2047: 2048: if description =~ /FI XME|TO DO/ then 2049: raise Gem::InvalidSpecificationException, "#{lazy} is not a description" 2050: end 2051: 2052: if summary =~ /FI XME|TO DO/ then 2053: raise Gem::InvalidSpecificationException, "#{lazy} is not a summary" 2054: end 2055: 2056: if homepage and not homepage.empty? and 2057: homepage !~ /\A[a-z][a-z\d+.-]*:/ then 2058: raise Gem::InvalidSpecificationException, 2059: "\"#{homepage}\" is not a URI" 2060: end 2061: 2062: # Warnings 2063: 2064: ]author description email homepage summary].each do |attribute| 2065: value = self.send attribute 2066: alert_warning "no #{attribute} specified" if value.nil? or value.empty? 2067: end 2068: 2069: if description == summary then 2070: alert_warning 'description and summary are identical' 2071: end 2072: 2073: # TODO: raise at some given date 2074: alert_warning "deprecated autorequire specified" if autorequire 2075: 2076: executables.each do |executable| 2077: executable_path = File.join(bindir, executable) 2078: shebang = File.read(executable_path, 2) == '#!' 2079: 2080: alert_warning "#{executable_path} is missing #! line" unless shebang 2081: end 2082: 2083: true 2084: 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 2091 2091: def version= version 2092: @version = Gem::Version.create(version) 2093: self.required_rubygems_version = '> 1.3.1' if @version.prerelease? 2094: return @version 2095: end
Adds a dependency on gem dependency with type type that requires requirements. Valid types are currently :runtime and :development.
# File lib/rubygems/specification.rb, line 795 795: def add_dependency_with_type(dependency, type, *requirements) 796: requirements = if requirements.empty? then 797: Gem::Requirement.default 798: else 799: requirements.flatten 800: end 801: 802: unless dependency.respond_to?(:name) && 803: dependency.respond_to?(:version_requirements) 804: 805: dependency = Gem::Dependency.new(dependency, requirements, type) 806: end 807: 808: dependencies << dependency 809: end
Finds all gems that satisfy dep
# File lib/rubygems/specification.rb, line 1210 1210: def find_all_satisfiers dep 1211: Gem::Specification.each do |spec| 1212: yield spec if spec.satisfies_requirement? dep 1213: end 1214: end
Return a string containing a Ruby code representation of the given object.
# File lib/rubygems/specification.rb, line 1691 1691: def ruby_code(obj) 1692: case obj 1693: when String then obj.dump 1694: when Array then '[' + obj.map { |x| ruby_code x }.join(", ") + ']' 1695: when Gem::Version then obj.to_s.dump 1696: when Date then obj.strftime('%Y-%m-%d').dump 1697: when Time then obj.strftime('%Y-%m-%d').dump 1698: when Numeric then obj.inspect 1699: when true, false, nil then obj.inspect 1700: when Gem::Platform then "Gem::Platform.new(#{obj.to_a.inspect})" 1701: when Gem::Requirement then "Gem::Requirement.new(#{obj.to_s.inspect})" 1702: else raise Gem::Exception, "ruby_code case not handled: #{obj.class}" 1703: end 1704: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.