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