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
|
# frozen_string_literal: true
module Bundler
# used for Creating Specifications from the Gemcutter Endpoint
class EndpointSpecification < Gem::Specification
ILLFORMED_MESSAGE = 'Ill-formed requirement ["#<YAML::Syck::DefaultKey'.freeze
include MatchPlatform
attr_reader :name, :version, :platform, :required_rubygems_version, :required_ruby_version, :checksum
attr_accessor :source, :remote, :dependencies
def initialize(name, version, platform, dependencies, metadata = nil)
super()
@name = name
@version = Gem::Version.create version
@platform = platform
@dependencies = dependencies.map {|dep, reqs| build_dependency(dep, reqs) }
@loaded_from = nil
@remote_specification = nil
parse_metadata(metadata)
end
def fetch_platform
@platform
end
# 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
def _local_specification
return unless @loaded_from && File.exist?(local_specification_path)
eval(File.read(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
private
def local_specification_path
"#{base_dir}/specifications/#{full_name}.gemspec"
end
def parse_metadata(data)
return unless data
data.each do |k, v|
next unless v
case k.to_s
when "checksum"
@checksum = v.last
when "rubygems"
@required_rubygems_version = Gem::Requirement.new(v)
when "ruby"
@required_ruby_version = Gem::Requirement.new(v)
end
end
rescue => 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)
Gem::Dependency.new(name, requirements)
rescue ArgumentError => e
raise unless e.message.include?(ILLFORMED_MESSAGE)
puts # we shouldn't print the error message on the "fetching info" status line
raise GemspecError,
"Unfortunately, the gem #{name} (#{version}) has an invalid " \
"gemspec.\nPlease ask the gem author to yank the bad version to fix " \
"this issue. For more information, see http://bit.ly/syck-defaultkey."
end
end
end
|