2016-02-01 07:43:26 -05:00
|
|
|
# frozen_string_literal: true
|
2013-08-26 16:24:51 -04:00
|
|
|
##
|
|
|
|
# Gem::StubSpecification reads the stub: line from the gemspec. This prevents
|
|
|
|
# us having to eval the entire gemspec in order to find out certain
|
|
|
|
# information.
|
|
|
|
|
|
|
|
class Gem::StubSpecification < Gem::BasicSpecification
|
|
|
|
# :nodoc:
|
|
|
|
PREFIX = "# stub: "
|
|
|
|
|
|
|
|
OPEN_MODE = # :nodoc:
|
|
|
|
if Object.const_defined? :Encoding then
|
|
|
|
'r:UTF-8:-'
|
|
|
|
else
|
|
|
|
'r'
|
|
|
|
end
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
class StubLine # :nodoc: all
|
2015-11-11 23:50:06 -05:00
|
|
|
attr_reader :name, :version, :platform, :require_paths, :extensions,
|
|
|
|
:full_name
|
|
|
|
|
|
|
|
NO_EXTENSIONS = [].freeze
|
|
|
|
|
|
|
|
# These are common require paths.
|
|
|
|
REQUIRE_PATHS = { # :nodoc:
|
|
|
|
'lib' => 'lib'.freeze,
|
|
|
|
'test' => 'test'.freeze,
|
|
|
|
'ext' => 'ext'.freeze,
|
|
|
|
}
|
|
|
|
|
|
|
|
# These are common require path lists. This hash is used to optimize
|
|
|
|
# and consolidate require_path objects. Most specs just specify "lib"
|
|
|
|
# in their require paths, so lets take advantage of that by pre-allocating
|
|
|
|
# a require path list for that case.
|
|
|
|
REQUIRE_PATH_LIST = { # :nodoc:
|
|
|
|
'lib' => ['lib'].freeze
|
|
|
|
}
|
|
|
|
|
|
|
|
def initialize data, extensions
|
|
|
|
parts = data[PREFIX.length..-1].split(" ".freeze, 4)
|
2015-10-29 20:54:12 -04:00
|
|
|
@name = parts[0].freeze
|
2015-07-01 17:50:14 -04:00
|
|
|
@version = Gem::Version.new parts[1]
|
|
|
|
@platform = Gem::Platform.new parts[2]
|
2015-11-11 23:50:06 -05:00
|
|
|
@extensions = extensions
|
|
|
|
@full_name = if platform == Gem::Platform::RUBY
|
|
|
|
"#{name}-#{version}"
|
|
|
|
else
|
|
|
|
"#{name}-#{version}-#{platform}"
|
|
|
|
end
|
|
|
|
|
|
|
|
path_list = parts.last
|
|
|
|
@require_paths = REQUIRE_PATH_LIST[path_list] || path_list.split("\0".freeze).map! { |x|
|
|
|
|
REQUIRE_PATHS[x] || x
|
|
|
|
}
|
2013-08-26 16:24:51 -04:00
|
|
|
end
|
2015-07-01 17:50:14 -04:00
|
|
|
end
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2015-11-11 23:50:06 -05:00
|
|
|
def self.default_gemspec_stub filename, base_dir, gems_dir
|
|
|
|
new filename, base_dir, gems_dir, true
|
2015-07-01 17:50:14 -04:00
|
|
|
end
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2015-11-11 23:50:06 -05:00
|
|
|
def self.gemspec_stub filename, base_dir, gems_dir
|
|
|
|
new filename, base_dir, gems_dir, false
|
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
|
|
|
attr_reader :base_dir, :gems_dir
|
|
|
|
|
|
|
|
def initialize filename, base_dir, gems_dir, default_gem
|
|
|
|
super()
|
2015-10-29 20:54:12 -04:00
|
|
|
filename.untaint
|
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
self.loaded_from = filename
|
|
|
|
@data = nil
|
2014-12-06 19:53:01 -05:00
|
|
|
@name = nil
|
2013-08-26 16:24:51 -04:00
|
|
|
@spec = nil
|
2015-11-11 23:50:06 -05:00
|
|
|
@base_dir = base_dir
|
|
|
|
@gems_dir = gems_dir
|
2015-07-01 17:50:14 -04:00
|
|
|
@default_gem = default_gem
|
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
|
|
|
##
|
|
|
|
# True when this gem has been activated
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
def activated?
|
2014-12-06 19:53:01 -05:00
|
|
|
@activated ||=
|
|
|
|
begin
|
|
|
|
loaded = Gem.loaded_specs[name]
|
|
|
|
loaded && loaded.version == version
|
|
|
|
end
|
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 default_gem?
|
|
|
|
@default_gem
|
|
|
|
end
|
|
|
|
|
2013-10-15 20:14:16 -04:00
|
|
|
def build_extensions # :nodoc:
|
|
|
|
return if default_gem?
|
|
|
|
return if extensions.empty?
|
|
|
|
|
|
|
|
to_spec.build_extensions
|
|
|
|
end
|
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
##
|
|
|
|
# If the gemspec contains a stubline, returns a StubLine instance. Otherwise
|
|
|
|
# returns the full Gem::Specification.
|
|
|
|
|
|
|
|
def data
|
|
|
|
unless @data
|
2015-09-09 05:18:47 -04:00
|
|
|
begin
|
|
|
|
saved_lineno = $.
|
|
|
|
open loaded_from, OPEN_MODE do |file|
|
|
|
|
begin
|
|
|
|
file.readline # discard encoding line
|
|
|
|
stubline = file.readline.chomp
|
|
|
|
if stubline.start_with?(PREFIX) then
|
2015-11-11 23:50:06 -05:00
|
|
|
extensions = if /\A#{PREFIX}/ =~ file.readline.chomp
|
|
|
|
$'.split "\0"
|
|
|
|
else
|
|
|
|
StubLine::NO_EXTENSIONS
|
|
|
|
end
|
2015-09-09 05:18:47 -04:00
|
|
|
|
2015-11-11 23:50:06 -05:00
|
|
|
@data = StubLine.new stubline, extensions
|
2015-09-09 05:18:47 -04:00
|
|
|
end
|
|
|
|
rescue EOFError
|
2013-10-15 20:14:16 -04:00
|
|
|
end
|
2013-08-26 16:24:51 -04:00
|
|
|
end
|
2015-09-09 05:18:47 -04:00
|
|
|
ensure
|
|
|
|
$. = saved_lineno
|
2013-08-26 16:24:51 -04:00
|
|
|
end
|
2013-07-09 19:21:36 -04:00
|
|
|
end
|
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
@data ||= to_spec
|
|
|
|
end
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
private :data
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2015-11-11 23:50:06 -05:00
|
|
|
def raw_require_paths # :nodoc:
|
|
|
|
data.require_paths
|
2013-10-15 20:14:16 -04:00
|
|
|
end
|
|
|
|
|
2014-09-13 23:30:02 -04:00
|
|
|
def missing_extensions?
|
|
|
|
return false if default_gem?
|
|
|
|
return false if extensions.empty?
|
2015-11-11 23:50:06 -05:00
|
|
|
return false if File.exist? gem_build_complete_path
|
2014-09-13 23:30:02 -04:00
|
|
|
|
|
|
|
to_spec.missing_extensions?
|
|
|
|
end
|
|
|
|
|
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
|
2015-07-01 17:50:14 -04:00
|
|
|
data.name
|
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
|
|
|
##
|
|
|
|
# Platform of the gem
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
def platform
|
2015-07-01 17:50:14 -04:00
|
|
|
data.platform
|
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
|
|
|
##
|
2015-11-11 23:50:06 -05:00
|
|
|
# Extensions for this gem
|
|
|
|
|
|
|
|
def extensions
|
|
|
|
data.extensions
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Version of the gem
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2015-11-11 23:50:06 -05:00
|
|
|
def version
|
|
|
|
data.version
|
|
|
|
end
|
2013-10-15 20:14:16 -04:00
|
|
|
|
2015-11-11 23:50:06 -05:00
|
|
|
def full_name
|
|
|
|
data.full_name
|
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
|
|
|
##
|
|
|
|
# The full Gem::Specification for this gem, loaded from evalling its gemspec
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
def to_spec
|
2014-12-06 19:53:01 -05:00
|
|
|
@spec ||= if @data then
|
|
|
|
Gem.loaded_specs.values.find { |spec|
|
|
|
|
spec.name == name and spec.version == version
|
|
|
|
}
|
|
|
|
end
|
2014-09-13 23:30:02 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
@spec ||= Gem::Specification.load(loaded_from)
|
2015-11-11 23:50:06 -05:00
|
|
|
@spec.ignored = @ignored if @spec
|
2014-09-13 23:30:02 -04:00
|
|
|
|
|
|
|
@spec
|
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
|
|
|
##
|
|
|
|
# Is this StubSpecification valid? i.e. have we found a stub line, OR does
|
|
|
|
# the filename contain a valid gemspec?
|
2013-07-09 19:21:36 -04:00
|
|
|
|
2013-08-26 16:24:51 -04:00
|
|
|
def valid?
|
|
|
|
data
|
2013-07-09 19:21:36 -04:00
|
|
|
end
|
2013-08-26 16:24:51 -04:00
|
|
|
|
2013-10-18 17:56:18 -04:00
|
|
|
##
|
|
|
|
# Is there a stub line present for this StubSpecification?
|
|
|
|
|
|
|
|
def stubbed?
|
|
|
|
data.is_a? StubLine
|
|
|
|
end
|
|
|
|
|
2013-07-09 19:21:36 -04:00
|
|
|
end
|