1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
# frozen_string_literal: true
module Bundler
# used for Creating Specifications from the Gemcutter Endpoint
class EndpointSpecification < Gem::Specification
include MatchRemoteMetadata
attr_reader :name, :version, :platform, :checksum
attr_writer :dependencies
attr_accessor :remote, :locked_platform
def initialize(name, version, platform, spec_fetcher, dependencies, metadata = nil)
super()
@name = name
@version = Gem::Version.create version
@platform = Gem::Platform.new(platform)
@spec_fetcher = spec_fetcher
@dependencies = nil
@unbuilt_dependencies = dependencies
@loaded_from = nil
@remote_specification = nil
@locked_platform = nil
parse_metadata(metadata)
end
def insecurely_materialized?
@locked_platform.to_s != @platform.to_s
end
def fetch_platform
@platform
end
def dependencies
@dependencies ||= @unbuilt_dependencies.map! {|dep, reqs| build_dependency(dep, reqs) }
end
alias_method :runtime_dependencies, :dependencies
# needed for standalone, load required_paths from local gemspec
# after the gem is installed
def require_paths
if @remote_specification
@remote_specification.require_paths
elsif _local_specification
_local_specification.require_paths
else
super
end
end
# needed for inline
def load_paths
# remote specs aren't installed, and can't have load_paths
if _local_specification
_local_specification.load_paths
else
super
end
end
# needed for binstubs
def executables
if @remote_specification
@remote_specification.executables
elsif _local_specification
_local_specification.executables
else
super
end
end
# needed for bundle clean
def bindir
if @remote_specification
@remote_specification.bindir
elsif _local_specification
_local_specification.bindir
else
super
end
end
# needed for post_install_messages during install
def post_install_message
if @remote_specification
@remote_specification.post_install_message
elsif _local_specification
_local_specification.post_install_message
else
super
end
end
# needed for "with native extensions" during install
def extensions
if @remote_specification
@remote_specification.extensions
elsif _local_specification
_local_specification.extensions
else
super
end
end
# needed for `bundle fund`
def metadata
if @remote_specification
@remote_specification.metadata
elsif _local_specification
_local_specification.metadata
else
super
end
end
def _local_specification
return unless @loaded_from && File.exist?(local_specification_path)
eval(File.read(local_specification_path), nil, local_specification_path).tap do |spec|
spec.loaded_from = @loaded_from
end
end
def __swap__(spec)
SharedHelpers.ensure_same_dependencies(self, dependencies, spec.dependencies)
@remote_specification = spec
end
def inspect
"#<#{self.class} @name=\"#{name}\" (#{full_name.delete_prefix("#{name}-")})>"
end
private
def _remote_specification
@_remote_specification ||= @spec_fetcher.fetch_spec([@name, @version, @platform])
end
def local_specification_path
"#{base_dir}/specifications/#{full_name}.gemspec"
end
def parse_metadata(data)
unless data
@required_ruby_version = nil
@required_rubygems_version = nil
return
end
data.each do |k, v|
next unless v
case k.to_s
when "checksum"
begin
@checksum = Checksum.from_api(v.last, @spec_fetcher.uri)
rescue ArgumentError => e
raise ArgumentError, "Invalid checksum for #{full_name}: #{e.message}"
end
when "rubygems"
@required_rubygems_version = Gem::Requirement.new(v)
when "ruby"
@required_ruby_version = Gem::Requirement.new(v)
end
end
rescue StandardError => e
raise GemspecError, "There was an error parsing the metadata for the gem #{name} (#{version}): #{e.class}\n#{e}\nThe metadata was #{data.inspect}"
end
def build_dependency(name, requirements)
Dependency.new(name, requirements)
end
end
end
|