summaryrefslogtreecommitdiff
path: root/lib/rubygems/basic_specification.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rubygems/basic_specification.rb')
-rw-r--r--lib/rubygems/basic_specification.rb198
1 files changed, 125 insertions, 73 deletions
diff --git a/lib/rubygems/basic_specification.rb b/lib/rubygems/basic_specification.rb
index 72954a7863..0ed7fc60bb 100644
--- a/lib/rubygems/basic_specification.rb
+++ b/lib/rubygems/basic_specification.rb
@@ -1,10 +1,10 @@
# frozen_string_literal: true
+
##
# BasicSpecification is an abstract class which implements some common code
# used by both Specification and StubSpecification.
class Gem::BasicSpecification
-
##
# Allows installation of extensions for git: gems.
@@ -34,16 +34,12 @@ class Gem::BasicSpecification
internal_init
end
- def self.default_specifications_dir
- File.join(Gem.default_dir, "specifications", "default")
- end
-
##
# 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'
+ File.join extension_dir, "gem.build_complete"
end
##
@@ -65,30 +61,58 @@ class Gem::BasicSpecification
##
# Return true if this spec can require +file+.
- def contains_requirable_file? file
- if @ignored then
- return false
- elsif missing_extensions? then
- @ignored = true
+ def contains_requirable_file?(file)
+ if ignored?
+ if platform == Gem::Platform::RUBY || Gem::Platform.local === platform
+ warn "Ignoring #{full_name} because its extensions are not built. " \
+ "Try: gem pristine #{name} --version #{version}"
+ end
- warn "Ignoring #{full_name} because its extensions are not built. " +
- "Try: gem pristine #{name} --version #{version}"
return false
end
- have_file? file, Gem.suffixes
+ is_soext = file.end_with?(".so", ".o")
+
+ if is_soext
+ have_file? file.delete_suffix(File.extname(file)), Gem.dynamic_library_suffixes
+ else
+ have_file? file, Gem.suffixes
+ end
+ end
+
+ ##
+ # Return true if this spec should be ignored because it's missing extensions.
+
+ def ignored?
+ return @ignored unless @ignored.nil?
+
+ @ignored = missing_extensions?
end
def default_gem?
- loaded_from &&
- File.dirname(loaded_from) == self.class.default_specifications_dir
+ !loaded_from.nil? &&
+ File.dirname(loaded_from) == Gem.default_specifications_dir
+ end
+
+ ##
+ # Regular gems take precedence over default gems
+
+ def default_gem_priority
+ default_gem? ? 1 : -1
+ end
+
+ ##
+ # Gems higher up in +gem_path+ take precedence
+
+ def base_dir_priority(gem_path)
+ gem_path.index(base_dir) || gem_path.size
end
##
# Returns full path to the directory where gem's extensions are installed.
def extension_dir
- @extension_dir ||= File.expand_path(File.join(extensions_dir, full_name)).untaint
+ @extension_dir ||= File.expand_path(File.join(extensions_dir, full_name))
end
##
@@ -96,25 +120,22 @@ class Gem::BasicSpecification
def extensions_dir
Gem.default_ext_dir_for(base_dir) ||
- File.join(base_dir, 'extensions', Gem::Platform.local.to_s,
+ File.join(base_dir, "extensions", Gem::Platform.local.to_s,
Gem.extension_api_version)
end
def find_full_gem_path # :nodoc:
- # TODO: also, shouldn't it default to full_name if it hasn't been written?
- path = File.expand_path File.join(gems_dir, full_name)
- path.untaint
- path
+ File.expand_path File.join(gems_dir, full_name)
end
private :find_full_gem_path
##
# The full path to the gem (install path + full name).
+ #
+ # TODO: This is duplicated with #gem_dir. Eventually either of them should be deprecated.
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
@@ -124,10 +145,23 @@ class Gem::BasicSpecification
# default Ruby platform.
def full_name
- if platform == Gem::Platform::RUBY or platform.nil? then
- "#{name}-#{version}".dup.untaint
+ if platform == Gem::Platform::RUBY || platform.nil?
+ "#{name}-#{version}"
+ else
+ "#{name}-#{version}-#{platform}"
+ end
+ end
+
+ ##
+ # Returns the full name of this Gem (see `Gem::BasicSpecification#full_name`).
+ # Information about where the gem is installed is also included if not
+ # installed in the default GEM_HOME.
+
+ def full_name_with_location
+ if base_dir != Gem.dir
+ "#{full_name} in #{base_dir}"
else
- "#{name}-#{version}-#{platform}".dup.untaint
+ full_name
end
end
@@ -137,53 +171,54 @@ class Gem::BasicSpecification
def full_require_paths
@full_require_paths ||=
- begin
- full_paths = raw_require_paths.map do |path|
- File.join full_gem_path, path.untaint
- end
+ begin
+ full_paths = raw_require_paths.map do |path|
+ File.join full_gem_path, path
+ end
- full_paths << extension_dir if have_extensions?
+ full_paths << extension_dir if have_extensions?
- full_paths
- end
+ full_paths
+ end
end
##
# The path to the data directory for this gem.
def datadir
-# TODO: drop the extra ", gem_name" which is uselessly redundant
- File.expand_path(File.join(gems_dir, full_name, "data", name)).untaint
+ # TODO: drop the extra ", gem_name" which is uselessly redundant
+ File.expand_path(File.join(gems_dir, full_name, "data", name))
end
+ extend Gem::Deprecate
+ rubygems_deprecate :datadir, :none, "4.1"
+
##
# Full path of the target library file.
# If the file is not in this gem, return nil.
- def to_fullpath path
- if activated? then
+ def to_fullpath(path)
+ if activated?
@paths_map ||= {}
- @paths_map[path] ||=
- begin
- fullpath = nil
- suffixes = Gem.suffixes
- suffixes.find do |suf|
- full_require_paths.find do |dir|
- File.file?(fullpath = "#{dir}/#{path}#{suf}")
- end
- end ? fullpath : nil
+ Gem.suffixes.each do |suf|
+ full_require_paths.each do |dir|
+ fullpath = "#{dir}/#{path}#{suf}"
+ next unless File.file?(fullpath)
+ @paths_map[path] ||= fullpath
+ end
end
- else
- nil
+ @paths_map[path]
end
end
##
# Returns the full path to this spec's gem directory.
# eg: /usr/local/lib/ruby/1.8/gems/mygem-1.0
+ #
+ # TODO: This is duplicated with #full_gem_path. Eventually either of them should be deprecated.
def gem_dir
- @gem_dir ||= File.expand_path File.join(gems_dir, full_name)
+ @gem_dir ||= find_full_gem_path
end
##
@@ -196,8 +231,8 @@ class Gem::BasicSpecification
def internal_init # :nodoc:
@extension_dir = nil
- @full_gem_path = nil
- @gem_dir = nil
+ @full_gem_path = nil
+ @gem_dir = nil
@ignored = nil
end
@@ -215,6 +250,13 @@ class Gem::BasicSpecification
raise NotImplementedError
end
+ def installable_on_platform?(target_platform) # :nodoc:
+ return true if [Gem::Platform::RUBY, nil, target_platform].include?(platform)
+ return true if Gem::Platform.new(platform) === target_platform
+
+ false
+ end
+
def raw_require_paths # :nodoc:
raise NotImplementedError
end
@@ -249,7 +291,7 @@ class Gem::BasicSpecification
def source_paths
paths = raw_require_paths.dup
- if have_extensions? then
+ if have_extensions?
ext_dirs = extensions.map do |extension|
extension.split(File::SEPARATOR, 2).first
end.uniq
@@ -263,11 +305,17 @@ class Gem::BasicSpecification
##
# Return all files in this gem that match for +glob+.
- def matches_for_glob glob # TODO: rename?
- # TODO: do we need these?? Kill it
- glob = File.join(self.lib_dirs_glob, glob)
+ def matches_for_glob(glob) # TODO: rename?
+ glob = File.join(lib_dirs_glob, glob)
+
+ Dir[glob]
+ end
+
+ ##
+ # Returns the list of plugins in this spec.
- Dir[glob].map { |f| f.untaint } # FIX our tests are broken, run w/ SAFE=1
+ def plugins
+ matches_for_glob("rubygems#{Gem.plugin_suffix_pattern}")
end
##
@@ -275,17 +323,17 @@ class Gem::BasicSpecification
# for this spec.
def lib_dirs_glob
- dirs = if self.raw_require_paths
- if self.raw_require_paths.size > 1 then
- "{#{self.raw_require_paths.join(',')}}"
- else
- self.raw_require_paths.first
- end
- else
- "lib" # default value for require_paths for bundler/inline
- end
+ dirs = if raw_require_paths
+ if raw_require_paths.size > 1
+ "{#{raw_require_paths.join(",")}}"
+ else
+ raw_require_paths.first
+ end
+ else
+ "lib" # default value for require_paths for bundler/inline
+ end
- "#{self.full_gem_path}/#{dirs}".dup.untaint
+ "#{full_gem_path}/#{dirs}"
end
##
@@ -310,21 +358,25 @@ class Gem::BasicSpecification
raise NotImplementedError
end
- def this; self; end
+ def this
+ self
+ end
private
- def have_extensions?; !extensions.empty?; end
+ def have_extensions?
+ !extensions.empty?
+ end
- def have_file? file, suffixes
+ def have_file?(file, suffixes)
return true if raw_require_paths.any? do |path|
- base = File.join(gems_dir, full_name, path.untaint, file).untaint
- suffixes.any? { |suf| File.file? base + suf }
+ base = File.join(gems_dir, full_name, path, file)
+ suffixes.any? {|suf| File.file? base + suf }
end
if have_extensions?
base = File.join extension_dir, file
- suffixes.any? { |suf| File.file? base + suf }
+ suffixes.any? {|suf| File.file? base + suf }
else
false
end