2016-02-01 07:43:26 -05:00
|
|
|
# frozen_string_literal: true
|
2013-08-26 16:24:51 -04:00
|
|
|
##
|
|
|
|
# BasicSpecification is an abstract class which implements some common code
|
|
|
|
# used by both Specification and StubSpecification.
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
class Gem::BasicSpecification
|
2013-11-30 18:27:52 -05:00
|
|
|
##
|
|
|
|
# Allows installation of extensions for git: gems.
|
|
|
|
|
|
|
|
attr_writer :base_dir # :nodoc:
|
|
|
|
|
|
|
|
##
|
|
|
|
# Sets the directory where extensions for this gem will be installed.
|
|
|
|
|
2013-12-10 14:54:19 -05:00
|
|
|
attr_writer :extension_dir # :nodoc:
|
2013-11-30 18:27:52 -05:00
|
|
|
|
2014-09-13 23:30:02 -04:00
|
|
|
##
|
|
|
|
# Is this specification ignored for activation purposes?
|
|
|
|
|
|
|
|
attr_writer :ignored # :nodoc:
|
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
##
|
|
|
|
# The path this gemspec was loaded from. This attribute is not persisted.
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2015-07-01 17:50:14 -04:00
|
|
|
attr_accessor :loaded_from
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-11-25 14:14:49 -05:00
|
|
|
##
|
|
|
|
# Allows correct activation of git: and path: gems.
|
|
|
|
|
|
|
|
attr_writer :full_gem_path # :nodoc:
|
|
|
|
|
2015-07-01 17:50:14 -04:00
|
|
|
def initialize
|
|
|
|
internal_init
|
|
|
|
end
|
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
def self.default_specifications_dir
|
2019-07-22 08:31:10 -04:00
|
|
|
Gem.default_specifications_dir
|
|
|
|
end
|
|
|
|
|
|
|
|
class << self
|
|
|
|
extend Gem::Deprecate
|
2020-04-19 09:41:54 -04:00
|
|
|
rubygems_deprecate :default_specifications_dir, "Gem.default_specifications_dir"
|
2013-08-26 16:24:51 -04:00
|
|
|
end
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2015-11-11 23:50:06 -05:00
|
|
|
##
|
|
|
|
# The path to the gem.build_complete file within the extension install
|
|
|
|
# directory.
|
|
|
|
|
|
|
|
def gem_build_complete_path # :nodoc:
|
|
|
|
File.join extension_dir, 'gem.build_complete'
|
|
|
|
end
|
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
##
|
|
|
|
# True when the gem has been activated
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
def activated?
|
|
|
|
raise NotImplementedError
|
|
|
|
end
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
##
|
|
|
|
# Returns the full path to the base gem directory.
|
|
|
|
#
|
|
|
|
# eg: /usr/local/lib/ruby/gems/1.8
|
|
|
|
|
|
|
|
def base_dir
|
2015-11-11 23:50:06 -05:00
|
|
|
raise NotImplementedError
|
2013-08-26 16:24:51 -04:00
|
|
|
end
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
##
|
|
|
|
# Return true if this spec can require +file+.
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2018-11-21 05:20:47 -05:00
|
|
|
def contains_requirable_file?(file)
|
|
|
|
if @ignored
|
2015-12-04 01:21:53 -05:00
|
|
|
return false
|
2018-11-21 05:20:47 -05:00
|
|
|
elsif missing_extensions?
|
2015-12-04 01:21:53 -05:00
|
|
|
@ignored = true
|
|
|
|
|
2020-04-07 12:09:13 -04:00
|
|
|
if Gem::Platform::RUBY == platform || Gem::Platform.local === platform
|
2019-03-07 06:24:48 -05:00
|
|
|
warn "Ignoring #{full_name} because its extensions are not built. " +
|
|
|
|
"Try: gem pristine #{name} --version #{version}"
|
|
|
|
end
|
|
|
|
|
2015-12-04 01:21:53 -05:00
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
have_file? file, Gem.suffixes
|
2013-08-26 16:24:51 -04:00
|
|
|
end
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
def default_gem?
|
|
|
|
loaded_from &&
|
2019-07-22 08:31:10 -04:00
|
|
|
File.dirname(loaded_from) == Gem.default_specifications_dir
|
2013-08-26 16:24:51 -04:00
|
|
|
end
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-10-15 20:14:16 -04:00
|
|
|
##
|
2013-12-10 14:54:19 -05:00
|
|
|
# Returns full path to the directory where gem's extensions are installed.
|
2013-10-15 20:14:16 -04:00
|
|
|
|
2013-12-10 14:54:19 -05:00
|
|
|
def extension_dir
|
2019-11-11 01:03:57 -05:00
|
|
|
@extension_dir ||= File.expand_path(File.join(extensions_dir, full_name)).tap(&Gem::UNTAINT)
|
2013-12-12 19:51:04 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Returns path to the extensions directory.
|
|
|
|
|
|
|
|
def extensions_dir
|
2016-03-03 19:29:40 -05:00
|
|
|
Gem.default_ext_dir_for(base_dir) ||
|
2013-12-12 19:51:04 -05:00
|
|
|
File.join(base_dir, 'extensions', Gem::Platform.local.to_s,
|
|
|
|
Gem.extension_api_version)
|
2013-10-15 20:14:16 -04:00
|
|
|
end
|
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
def find_full_gem_path # :nodoc:
|
|
|
|
# TODO: also, shouldn't it default to full_name if it hasn't been written?
|
2013-12-14 19:51:37 -05:00
|
|
|
path = File.expand_path File.join(gems_dir, full_name)
|
2019-11-11 01:03:57 -05:00
|
|
|
path.tap(&Gem::UNTAINT)
|
2015-11-11 23:50:06 -05:00
|
|
|
path
|
2013-08-26 16:24:51 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
private :find_full_gem_path
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
##
|
|
|
|
# The full path to the gem (install path + full name).
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
def full_gem_path
|
|
|
|
# TODO: This is a heavily used method by gems, so we'll need
|
|
|
|
# to aleast just alias it to #gem_dir rather than remove it.
|
|
|
|
@full_gem_path ||= find_full_gem_path
|
|
|
|
end
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
##
|
|
|
|
# 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.
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
def full_name
|
2018-11-21 05:20:47 -05:00
|
|
|
if platform == Gem::Platform::RUBY or platform.nil?
|
2019-11-11 01:03:57 -05:00
|
|
|
"#{name}-#{version}".dup.tap(&Gem::UNTAINT)
|
2013-08-26 16:24:51 -04:00
|
|
|
else
|
2019-11-11 01:03:57 -05:00
|
|
|
"#{name}-#{version}-#{platform}".dup.tap(&Gem::UNTAINT)
|
2013-07-09 19:21:36 -04:00
|
|
|
end
|
2013-08-26 16:24:51 -04:00
|
|
|
end
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-10-15 20:14:16 -04:00
|
|
|
##
|
|
|
|
# Full paths in the gem to add to <code>$LOAD_PATH</code> when this gem is
|
|
|
|
# activated.
|
|
|
|
|
|
|
|
def full_require_paths
|
2014-12-06 19:53:01 -05:00
|
|
|
@full_require_paths ||=
|
|
|
|
begin
|
|
|
|
full_paths = raw_require_paths.map do |path|
|
2019-11-11 01:03:57 -05:00
|
|
|
File.join full_gem_path, path.tap(&Gem::UNTAINT)
|
2014-12-06 19:53:01 -05:00
|
|
|
end
|
2013-10-15 20:14:16 -04:00
|
|
|
|
2015-11-11 23:50:06 -05:00
|
|
|
full_paths << extension_dir if have_extensions?
|
2013-10-15 20:14:16 -04:00
|
|
|
|
2014-12-06 19:53:01 -05:00
|
|
|
full_paths
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-11-11 23:50:06 -05:00
|
|
|
##
|
|
|
|
# The path to the data directory for this gem.
|
|
|
|
|
|
|
|
def datadir
|
2018-08-27 06:05:04 -04:00
|
|
|
# TODO: drop the extra ", gem_name" which is uselessly redundant
|
2019-11-11 01:03:57 -05:00
|
|
|
File.expand_path(File.join(gems_dir, full_name, "data", name)).tap(&Gem::UNTAINT)
|
2015-11-11 23:50:06 -05:00
|
|
|
end
|
|
|
|
|
2014-12-06 19:53:01 -05:00
|
|
|
##
|
|
|
|
# Full path of the target library file.
|
|
|
|
# If the file is not in this gem, return nil.
|
|
|
|
|
2018-11-21 05:20:47 -05:00
|
|
|
def to_fullpath(path)
|
|
|
|
if activated?
|
2014-12-06 19:53:01 -05:00
|
|
|
@paths_map ||= {}
|
|
|
|
@paths_map[path] ||=
|
|
|
|
begin
|
|
|
|
fullpath = nil
|
|
|
|
suffixes = Gem.suffixes
|
2015-11-19 01:16:19 -05:00
|
|
|
suffixes.find do |suf|
|
|
|
|
full_require_paths.find do |dir|
|
2014-12-06 19:53:01 -05:00
|
|
|
File.file?(fullpath = "#{dir}/#{path}#{suf}")
|
|
|
|
end
|
|
|
|
end ? fullpath : nil
|
|
|
|
end
|
|
|
|
else
|
|
|
|
nil
|
|
|
|
end
|
2013-10-15 20:14:16 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Returns the full path to this spec's gem directory.
|
|
|
|
# eg: /usr/local/lib/ruby/1.8/gems/mygem-1.0
|
|
|
|
|
|
|
|
def gem_dir
|
|
|
|
@gem_dir ||= File.expand_path File.join(gems_dir, full_name)
|
|
|
|
end
|
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
##
|
|
|
|
# Returns the full path to the gems directory containing this spec's
|
|
|
|
# gem directory. eg: /usr/local/lib/ruby/1.8/gems
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
def gems_dir
|
2015-11-11 23:50:06 -05:00
|
|
|
raise NotImplementedError
|
2013-08-26 16:24:51 -04:00
|
|
|
end
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2015-07-01 17:50:14 -04:00
|
|
|
def internal_init # :nodoc:
|
2013-12-10 14:54:19 -05:00
|
|
|
@extension_dir = nil
|
2019-08-22 11:36:29 -04:00
|
|
|
@full_gem_path = nil
|
|
|
|
@gem_dir = nil
|
2015-11-11 23:50:06 -05:00
|
|
|
@ignored = nil
|
2013-08-26 16:24:51 -04:00
|
|
|
end
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
##
|
|
|
|
# Name of the gem
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
def name
|
|
|
|
raise NotImplementedError
|
|
|
|
end
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
##
|
|
|
|
# Platform of the gem
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
def platform
|
|
|
|
raise NotImplementedError
|
|
|
|
end
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-11-18 19:34:13 -05:00
|
|
|
def raw_require_paths # :nodoc:
|
2015-11-11 23:50:06 -05:00
|
|
|
raise NotImplementedError
|
2013-11-18 19:34:13 -05:00
|
|
|
end
|
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
##
|
2013-10-15 20:14:16 -04:00
|
|
|
# Paths in the gem to add to <code>$LOAD_PATH</code> when this gem is
|
|
|
|
# activated.
|
|
|
|
#
|
|
|
|
# See also #require_paths=
|
|
|
|
#
|
|
|
|
# If you have an extension you do not need to add <code>"ext"</code> to the
|
|
|
|
# require path, the extension build process will copy the extension files
|
|
|
|
# into "lib" for you.
|
|
|
|
#
|
|
|
|
# The default value is <code>"lib"</code>
|
|
|
|
#
|
|
|
|
# Usage:
|
|
|
|
#
|
|
|
|
# # If all library files are in the root directory...
|
|
|
|
# spec.require_path = '.'
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
def require_paths
|
2015-11-11 23:50:06 -05:00
|
|
|
return raw_require_paths unless have_extensions?
|
2013-10-15 20:14:16 -04:00
|
|
|
|
2014-09-13 23:30:02 -04:00
|
|
|
[extension_dir].concat raw_require_paths
|
2013-07-09 19:21:36 -04:00
|
|
|
end
|
2013-08-26 16:24:51 -04:00
|
|
|
|
2014-01-06 20:19:28 -05:00
|
|
|
##
|
|
|
|
# Returns the paths to the source files for use with analysis and
|
|
|
|
# documentation tools. These paths are relative to full_gem_path.
|
|
|
|
|
|
|
|
def source_paths
|
|
|
|
paths = raw_require_paths.dup
|
|
|
|
|
2018-11-21 05:20:47 -05:00
|
|
|
if have_extensions?
|
2015-11-11 23:50:06 -05:00
|
|
|
ext_dirs = extensions.map do |extension|
|
2014-01-06 20:19:28 -05:00
|
|
|
extension.split(File::SEPARATOR, 2).first
|
|
|
|
end.uniq
|
|
|
|
|
|
|
|
paths.concat ext_dirs
|
|
|
|
end
|
|
|
|
|
|
|
|
paths.uniq
|
|
|
|
end
|
|
|
|
|
2015-07-01 17:50:14 -04:00
|
|
|
##
|
|
|
|
# Return all files in this gem that match for +glob+.
|
|
|
|
|
2018-11-21 05:20:47 -05:00
|
|
|
def matches_for_glob(glob) # TODO: rename?
|
2015-07-01 17:50:14 -04:00
|
|
|
glob = File.join(self.lib_dirs_glob, glob)
|
|
|
|
|
2020-06-10 13:46:05 -04:00
|
|
|
Dir[glob].map {|f| f.tap(&Gem::UNTAINT) } # FIX our tests are broken, run w/ SAFE=1
|
2015-07-01 17:50:14 -04:00
|
|
|
end
|
|
|
|
|
2020-01-31 21:14:04 -05:00
|
|
|
##
|
|
|
|
# Returns the list of plugins in this spec.
|
|
|
|
|
|
|
|
def plugins
|
|
|
|
matches_for_glob("rubygems#{Gem.plugin_suffix_pattern}")
|
|
|
|
end
|
|
|
|
|
2015-07-01 17:50:14 -04:00
|
|
|
##
|
|
|
|
# Returns a string usable in Dir.glob to match all requirable paths
|
|
|
|
# for this spec.
|
|
|
|
|
|
|
|
def lib_dirs_glob
|
2017-10-20 05:03:37 -04:00
|
|
|
dirs = if self.raw_require_paths
|
2022-01-17 09:16:34 -05:00
|
|
|
if self.raw_require_paths.size > 1
|
|
|
|
"{#{self.raw_require_paths.join(',')}}"
|
|
|
|
else
|
|
|
|
self.raw_require_paths.first
|
|
|
|
end
|
|
|
|
else
|
|
|
|
"lib" # default value for require_paths for bundler/inline
|
|
|
|
end
|
2015-07-01 17:50:14 -04:00
|
|
|
|
2019-11-11 01:03:57 -05:00
|
|
|
"#{self.full_gem_path}/#{dirs}".dup.tap(&Gem::UNTAINT)
|
2015-07-01 17:50:14 -04:00
|
|
|
end
|
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
##
|
|
|
|
# Return a Gem::Specification from this gem
|
|
|
|
|
|
|
|
def to_spec
|
|
|
|
raise NotImplementedError
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Version of the gem
|
|
|
|
|
|
|
|
def version
|
|
|
|
raise NotImplementedError
|
|
|
|
end
|
|
|
|
|
2013-11-10 12:51:40 -05:00
|
|
|
##
|
|
|
|
# Whether this specification is stubbed - i.e. we have information
|
|
|
|
# about the gem from a stub line, without having to evaluate the
|
|
|
|
# entire gemspec file.
|
|
|
|
def stubbed?
|
|
|
|
raise NotImplementedError
|
|
|
|
end
|
|
|
|
|
2016-04-06 02:01:14 -04:00
|
|
|
def this; self; end
|
|
|
|
|
2015-11-11 23:50:06 -05:00
|
|
|
private
|
|
|
|
|
|
|
|
def have_extensions?; !extensions.empty?; end
|
|
|
|
|
2018-11-21 05:20:47 -05:00
|
|
|
def have_file?(file, suffixes)
|
2015-11-11 23:50:06 -05:00
|
|
|
return true if raw_require_paths.any? do |path|
|
2019-11-11 01:03:57 -05:00
|
|
|
base = File.join(gems_dir, full_name, path.tap(&Gem::UNTAINT), file).tap(&Gem::UNTAINT)
|
2020-06-10 13:46:05 -04:00
|
|
|
suffixes.any? {|suf| File.file? base + suf }
|
2015-11-11 23:50:06 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
if have_extensions?
|
|
|
|
base = File.join extension_dir, file
|
2020-06-10 13:46:05 -04:00
|
|
|
suffixes.any? {|suf| File.file? base + suf }
|
2015-11-11 23:50:06 -05:00
|
|
|
else
|
|
|
|
false
|
|
|
|
end
|
|
|
|
end
|
2013-07-09 19:21:36 -04:00
|
|
|
end
|