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_versionPaths 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.