moneypools-bundler 0.7.1.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.markdown +275 -0
- data/Rakefile +60 -0
- data/lib/bundler.rb +35 -0
- data/lib/bundler/cli.rb +69 -0
- data/lib/bundler/commands/bundle_command.rb +72 -0
- data/lib/bundler/commands/exec_command.rb +36 -0
- data/lib/bundler/dependency.rb +64 -0
- data/lib/bundler/dsl.rb +173 -0
- data/lib/bundler/environment.rb +181 -0
- data/lib/bundler/finder.rb +51 -0
- data/lib/bundler/gem_bundle.rb +11 -0
- data/lib/bundler/gem_ext.rb +33 -0
- data/lib/bundler/remote_specification.rb +50 -0
- data/lib/bundler/repository.rb +256 -0
- data/lib/bundler/resolver.rb +234 -0
- data/lib/bundler/runtime.rb +2 -0
- data/lib/bundler/source.rb +326 -0
- data/lib/bundler/templates/app_script.erb +3 -0
- data/lib/bundler/templates/environment.erb +142 -0
- data/lib/rubygems_plugin.rb +6 -0
- metadata +79 -0
@@ -0,0 +1,326 @@
|
|
1
|
+
module Bundler
|
2
|
+
class DirectorySourceError < StandardError; end
|
3
|
+
class GitSourceError < StandardError ; end
|
4
|
+
# Represents a source of rubygems. Initially, this is only gem repositories, but
|
5
|
+
# eventually, this will be git, svn, HTTP
|
6
|
+
class Source
|
7
|
+
attr_accessor :repository, :local
|
8
|
+
|
9
|
+
def initialize(options) ; end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def process_source_gems(gems)
|
14
|
+
new_gems = Hash.new { |h,k| h[k] = [] }
|
15
|
+
gems.values.each do |spec|
|
16
|
+
spec.source = self
|
17
|
+
new_gems[spec.name] << spec
|
18
|
+
end
|
19
|
+
new_gems
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class GemSource < Source
|
24
|
+
attr_reader :uri
|
25
|
+
|
26
|
+
def initialize(options)
|
27
|
+
@uri = options[:uri]
|
28
|
+
@uri = URI.parse(@uri) unless @uri.is_a?(URI)
|
29
|
+
raise ArgumentError, "The source must be an absolute URI" unless @uri.absolute?
|
30
|
+
end
|
31
|
+
|
32
|
+
def can_be_local?
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
36
|
+
def gems
|
37
|
+
@specs ||= fetch_specs
|
38
|
+
end
|
39
|
+
|
40
|
+
def ==(other)
|
41
|
+
uri == other.uri
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_s
|
45
|
+
@uri.to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
class RubygemsRetardation < StandardError; end
|
49
|
+
|
50
|
+
def download(spec)
|
51
|
+
Bundler.logger.info "Downloading #{spec.full_name}.gem"
|
52
|
+
|
53
|
+
destination = repository.path
|
54
|
+
|
55
|
+
unless destination.writable?
|
56
|
+
raise RubygemsRetardation, "destination: #{destination} is not writable"
|
57
|
+
end
|
58
|
+
|
59
|
+
# Download the gem
|
60
|
+
Gem::RemoteFetcher.fetcher.download(spec, uri, destination)
|
61
|
+
|
62
|
+
# Re-read the gemspec from the downloaded gem to correct
|
63
|
+
# any errors that were present in the Rubyforge specification.
|
64
|
+
new_spec = Gem::Format.from_file_by_path(destination.join('cache', "#{spec.full_name}.gem")).spec
|
65
|
+
spec.__swap__(new_spec)
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def fetch_specs
|
71
|
+
Bundler.logger.info "Updating source: #{to_s}"
|
72
|
+
|
73
|
+
fetcher = Gem::RemoteFetcher.fetcher
|
74
|
+
main_index = fetcher.fetch_path("#{uri}/specs.4.8.gz")
|
75
|
+
begin
|
76
|
+
prerelease_index = fetcher.fetch_path("#{uri}/prerelease_specs.4.8.gz")
|
77
|
+
index = Marshal.load(main_index) + Marshal.load(prerelease_index)
|
78
|
+
rescue Gem::RemoteFetcher::FetchError
|
79
|
+
Bundler.logger.warn "Source '#{uri}' does not support prerelease gems"
|
80
|
+
index = Marshal.load(main_index)
|
81
|
+
end
|
82
|
+
|
83
|
+
gems = Hash.new { |h,k| h[k] = [] }
|
84
|
+
index.each do |name, version, platform|
|
85
|
+
spec = RemoteSpecification.new(name, version, platform, @uri)
|
86
|
+
spec.source = self
|
87
|
+
gems[spec.name] << spec if Gem::Platform.match(spec.platform)
|
88
|
+
end
|
89
|
+
gems
|
90
|
+
rescue Gem::RemoteFetcher::FetchError => e
|
91
|
+
raise ArgumentError, "#{to_s} is not a valid source: #{e.message}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class SystemGemSource < Source
|
96
|
+
|
97
|
+
def self.instance
|
98
|
+
@instance ||= new({})
|
99
|
+
end
|
100
|
+
|
101
|
+
def initialize(options)
|
102
|
+
@source = Gem::SourceIndex.from_installed_gems
|
103
|
+
end
|
104
|
+
|
105
|
+
def can_be_local?
|
106
|
+
false
|
107
|
+
end
|
108
|
+
|
109
|
+
def gems
|
110
|
+
@gems ||= process_source_gems(@source.gems)
|
111
|
+
end
|
112
|
+
|
113
|
+
def ==(other)
|
114
|
+
other.is_a?(SystemGemSource)
|
115
|
+
end
|
116
|
+
|
117
|
+
def to_s
|
118
|
+
"system"
|
119
|
+
end
|
120
|
+
|
121
|
+
def download(spec)
|
122
|
+
gemfile = Pathname.new(spec.loaded_from)
|
123
|
+
gemfile = gemfile.dirname.join('..', 'cache', "#{spec.full_name}.gem")
|
124
|
+
repository.cache(gemfile)
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
class GemDirectorySource < Source
|
132
|
+
attr_reader :location
|
133
|
+
|
134
|
+
def initialize(options)
|
135
|
+
@location = options[:location]
|
136
|
+
end
|
137
|
+
|
138
|
+
def can_be_local?
|
139
|
+
true
|
140
|
+
end
|
141
|
+
|
142
|
+
def gems
|
143
|
+
@specs ||= fetch_specs
|
144
|
+
end
|
145
|
+
|
146
|
+
def ==(other)
|
147
|
+
location == other.location
|
148
|
+
end
|
149
|
+
|
150
|
+
def to_s
|
151
|
+
location.to_s
|
152
|
+
end
|
153
|
+
|
154
|
+
def download(spec)
|
155
|
+
# raise NotImplementedError
|
156
|
+
end
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
def fetch_specs
|
161
|
+
specs = Hash.new { |h,k| h[k] = [] }
|
162
|
+
|
163
|
+
Dir["#{@location}/*.gem"].each do |gemfile|
|
164
|
+
spec = Gem::Format.from_file_by_path(gemfile).spec
|
165
|
+
spec.source = self
|
166
|
+
specs[spec.name] << spec
|
167
|
+
end
|
168
|
+
|
169
|
+
specs
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
class DirectorySource < Source
|
174
|
+
attr_reader :location, :specs, :required_specs
|
175
|
+
|
176
|
+
def initialize(options)
|
177
|
+
if options[:location]
|
178
|
+
@location = Pathname.new(options[:location]).expand_path
|
179
|
+
end
|
180
|
+
@glob = options[:glob] || "**/*.gemspec"
|
181
|
+
@specs = {}
|
182
|
+
@required_specs = []
|
183
|
+
end
|
184
|
+
|
185
|
+
def add_spec(path, name, version, require_paths = %w(lib))
|
186
|
+
raise DirectorySourceError, "already have a gem defined for '#{path}'" if @specs[path.to_s]
|
187
|
+
@specs[path.to_s] = Gem::Specification.new do |s|
|
188
|
+
s.name = name
|
189
|
+
s.version = Gem::Version.new(version)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def can_be_local?
|
194
|
+
true
|
195
|
+
end
|
196
|
+
|
197
|
+
def gems
|
198
|
+
@gems ||= begin
|
199
|
+
# Locate all gemspecs from the directory
|
200
|
+
specs = locate_gemspecs
|
201
|
+
specs = merge_defined_specs(specs)
|
202
|
+
|
203
|
+
required_specs.each do |required|
|
204
|
+
unless specs.any? {|k,v| v.name == required }
|
205
|
+
raise DirectorySourceError, "No gemspec for '#{required}' was found in" \
|
206
|
+
" '#{location}'. Please explicitly specify a version."
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
process_source_gems(specs)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def locate_gemspecs
|
215
|
+
Dir["#{location}/#{@glob}"].inject({}) do |specs, file|
|
216
|
+
file = Pathname.new(file)
|
217
|
+
if spec = eval(File.read(file)) and validate_gemspec(file.dirname, spec)
|
218
|
+
spec.location = file.dirname.expand_path
|
219
|
+
specs[spec.full_name] = spec
|
220
|
+
end
|
221
|
+
specs
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def merge_defined_specs(specs)
|
226
|
+
@specs.each do |path, spec|
|
227
|
+
# Set the spec location
|
228
|
+
spec.location = "#{location}/#{path}"
|
229
|
+
|
230
|
+
if existing = specs.values.find { |s| s.name == spec.name }
|
231
|
+
if existing.version != spec.version
|
232
|
+
raise DirectorySourceError, "The version you specified for #{spec.name}" \
|
233
|
+
" is #{spec.version}. The gemspec is #{existing.version}."
|
234
|
+
# Not sure if this is needed
|
235
|
+
# ====
|
236
|
+
# elsif File.expand_path(existing.location) != File.expand_path(spec.location)
|
237
|
+
# raise DirectorySourceError, "The location you specified for #{spec.name}" \
|
238
|
+
# " is '#{spec.location}'. The gemspec was found at '#{existing.location}'."
|
239
|
+
end
|
240
|
+
elsif !validate_gemspec(spec.location, spec)
|
241
|
+
raise "Your gem definition is not valid: #{spec}"
|
242
|
+
else
|
243
|
+
specs[spec.full_name] = spec
|
244
|
+
end
|
245
|
+
end
|
246
|
+
specs
|
247
|
+
end
|
248
|
+
|
249
|
+
def validate_gemspec(path, spec)
|
250
|
+
path = Pathname.new(path)
|
251
|
+
msg = "Gemspec for #{spec.name} (#{spec.version}) is invalid:"
|
252
|
+
# Check the require_paths
|
253
|
+
(spec.require_paths || []).each do |require_path|
|
254
|
+
unless path.join(require_path).directory?
|
255
|
+
Bundler.logger.warn "#{msg} Missing require path: '#{require_path}'"
|
256
|
+
return false
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
# Check the executables
|
261
|
+
(spec.executables || []).each do |exec|
|
262
|
+
unless path.join(spec.bindir, exec).file?
|
263
|
+
Bundler.logger.warn "#{msg} Missing executable: '#{File.join(spec.bindir, exec)}'"
|
264
|
+
return false
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
true
|
269
|
+
end
|
270
|
+
|
271
|
+
def ==(other)
|
272
|
+
# TMP HAX
|
273
|
+
other.is_a?(DirectorySource)
|
274
|
+
end
|
275
|
+
|
276
|
+
def to_s
|
277
|
+
"#{@name} (#{@version}) Located at: '#{location}'"
|
278
|
+
end
|
279
|
+
|
280
|
+
def download(spec)
|
281
|
+
# Nothing needed here
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
class GitSource < DirectorySource
|
286
|
+
attr_reader :ref, :uri, :branch
|
287
|
+
|
288
|
+
def initialize(options)
|
289
|
+
super
|
290
|
+
@uri = options[:uri]
|
291
|
+
@ref = options[:ref]
|
292
|
+
@branch = options[:branch]
|
293
|
+
end
|
294
|
+
|
295
|
+
def location
|
296
|
+
# TMP HAX to get the *.gemspec reading to work
|
297
|
+
repository.path.join('dirs', File.basename(@uri, '.git'))
|
298
|
+
end
|
299
|
+
|
300
|
+
def gems
|
301
|
+
unless location.directory?
|
302
|
+
# Raise an error if the source should run in local mode,
|
303
|
+
# but it has not been cached yet.
|
304
|
+
if local
|
305
|
+
raise SourceNotCached, "Git repository '#{@uri}' has not been cloned yet"
|
306
|
+
end
|
307
|
+
|
308
|
+
FileUtils.mkdir_p(location.dirname)
|
309
|
+
|
310
|
+
Bundler.logger.info "Cloning git repository at: #{@uri}"
|
311
|
+
`git clone #{@uri} #{location} --no-hardlinks`
|
312
|
+
|
313
|
+
if @ref
|
314
|
+
Dir.chdir(location) { `git checkout --quiet #{@ref}` }
|
315
|
+
elsif @branch && @branch != "master"
|
316
|
+
Dir.chdir(location) { `git checkout --quiet origin/#{@branch}` }
|
317
|
+
end
|
318
|
+
end
|
319
|
+
super
|
320
|
+
end
|
321
|
+
|
322
|
+
def download(spec)
|
323
|
+
# Nothing needed here
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
@@ -0,0 +1,3 @@
|
|
1
|
+
<%= shebang bin_file_name %>
|
2
|
+
require File.join(File.dirname(__FILE__), "<%= path.join("environment").relative_path_from(Pathname.new(bin_dir)) %>")
|
3
|
+
load File.join(File.dirname(__FILE__), "<%= path.join("gems", @spec.full_name, @spec.bindir, bin_file_name).relative_path_from(Pathname.new(bin_dir)) %>")
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# DO NOT MODIFY THIS FILE
|
2
|
+
module Bundler
|
3
|
+
file = File.expand_path(__FILE__)
|
4
|
+
dir = File.dirname(file)
|
5
|
+
|
6
|
+
<% unless options[:system_gems] -%>
|
7
|
+
ENV["GEM_HOME"] = dir
|
8
|
+
ENV["GEM_PATH"] = dir
|
9
|
+
<% end -%>
|
10
|
+
ENV["PATH"] = "#{dir}/<%= bindir %>:#{ENV["PATH"]}"
|
11
|
+
ENV["RUBYOPT"] = "-r#{file} #{ENV["RUBYOPT"]}"
|
12
|
+
|
13
|
+
<% load_paths.each do |load_path| -%>
|
14
|
+
$LOAD_PATH.unshift File.expand_path("#{dir}/<%= load_path %>")
|
15
|
+
<% end -%>
|
16
|
+
|
17
|
+
@gemfile = "#{dir}/<%= filename %>"
|
18
|
+
|
19
|
+
<% if options[:rubygems] -%>
|
20
|
+
require "rubygems"
|
21
|
+
|
22
|
+
@bundled_specs = {}
|
23
|
+
<% specs.each do |spec| -%>
|
24
|
+
<% if options[:no_bundle].include?(spec.name) -%>
|
25
|
+
gem "<%= spec.name %>", "<%= spec.version %>"
|
26
|
+
<% else -%>
|
27
|
+
<% path = spec_file_for(spec) -%>
|
28
|
+
@bundled_specs["<%= spec.name %>"] = eval(File.read("#{dir}/<%= path %>"))
|
29
|
+
@bundled_specs["<%= spec.name %>"].loaded_from = "#{dir}/<%= path %>"
|
30
|
+
<% end -%>
|
31
|
+
<% end -%>
|
32
|
+
|
33
|
+
def self.add_specs_to_loaded_specs
|
34
|
+
Gem.loaded_specs.merge! @bundled_specs
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.add_specs_to_index
|
38
|
+
@bundled_specs.each do |name, spec|
|
39
|
+
Gem.source_index.add_spec spec
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
add_specs_to_loaded_specs
|
44
|
+
add_specs_to_index
|
45
|
+
<% end -%>
|
46
|
+
|
47
|
+
def self.require_env(env = nil)
|
48
|
+
context = Class.new do
|
49
|
+
def initialize(env) @env = env && env.to_s ; end
|
50
|
+
def method_missing(*) ; yield if block_given? ; end
|
51
|
+
def only(*env)
|
52
|
+
old, @only = @only, _combine_only(env.flatten)
|
53
|
+
yield
|
54
|
+
@only = old
|
55
|
+
end
|
56
|
+
def except(*env)
|
57
|
+
old, @except = @except, _combine_except(env.flatten)
|
58
|
+
yield
|
59
|
+
@except = old
|
60
|
+
end
|
61
|
+
def gem(name, *args)
|
62
|
+
opt = args.last.is_a?(Hash) ? args.pop : {}
|
63
|
+
only = _combine_only(opt[:only] || opt["only"])
|
64
|
+
except = _combine_except(opt[:except] || opt["except"])
|
65
|
+
|
66
|
+
return unless !only || only.any? {|e| e == @env }
|
67
|
+
return if except && except.any? {|e| e == @env }
|
68
|
+
|
69
|
+
if files = opt[:require_as] || opt["require_as"]
|
70
|
+
Array(files).each { |f| require f }
|
71
|
+
elsif opt[:require_as].nil? && opt["require_as"].nil?
|
72
|
+
begin
|
73
|
+
require name
|
74
|
+
rescue LoadError
|
75
|
+
# Do nothing
|
76
|
+
end
|
77
|
+
end
|
78
|
+
yield if block_given?
|
79
|
+
true
|
80
|
+
end
|
81
|
+
private
|
82
|
+
def _combine_only(only)
|
83
|
+
return @only unless only
|
84
|
+
only = [only].flatten.compact.uniq.map { |o| o.to_s }
|
85
|
+
only &= @only if @only
|
86
|
+
only
|
87
|
+
end
|
88
|
+
def _combine_except(except)
|
89
|
+
return @except unless except
|
90
|
+
except = [except].flatten.compact.uniq.map { |o| o.to_s }
|
91
|
+
except |= @except if @except
|
92
|
+
except
|
93
|
+
end
|
94
|
+
end
|
95
|
+
context.new(env && env.to_s).instance_eval(File.read(@gemfile), @gemfile, 1)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
<% if options[:rubygems] -%>
|
100
|
+
module Gem
|
101
|
+
@loaded_stacks = Hash.new { |h,k| h[k] = [] }
|
102
|
+
|
103
|
+
def source_index.refresh!
|
104
|
+
super
|
105
|
+
Bundler.add_specs_to_index
|
106
|
+
end
|
107
|
+
end
|
108
|
+
<% else -%>
|
109
|
+
$" << "rubygems.rb"
|
110
|
+
|
111
|
+
module Kernel
|
112
|
+
def gem(*)
|
113
|
+
# Silently ignore calls to gem, since, in theory, everything
|
114
|
+
# is activated correctly already.
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Define all the Gem errors for gems that reference them.
|
119
|
+
module Gem
|
120
|
+
def self.ruby ; <%= Gem.ruby.inspect %> ; end
|
121
|
+
class LoadError < ::LoadError; end
|
122
|
+
class Exception < RuntimeError; end
|
123
|
+
class CommandLineError < Exception; end
|
124
|
+
class DependencyError < Exception; end
|
125
|
+
class DependencyRemovalException < Exception; end
|
126
|
+
class GemNotInHomeException < Exception ; end
|
127
|
+
class DocumentError < Exception; end
|
128
|
+
class EndOfYAMLException < Exception; end
|
129
|
+
class FilePermissionError < Exception; end
|
130
|
+
class FormatException < Exception; end
|
131
|
+
class GemNotFoundException < Exception; end
|
132
|
+
class InstallError < Exception; end
|
133
|
+
class InvalidSpecificationException < Exception; end
|
134
|
+
class OperationNotSupportedError < Exception; end
|
135
|
+
class RemoteError < Exception; end
|
136
|
+
class RemoteInstallationCancelled < Exception; end
|
137
|
+
class RemoteInstallationSkipped < Exception; end
|
138
|
+
class RemoteSourceException < Exception; end
|
139
|
+
class VerificationError < Exception; end
|
140
|
+
class SystemExitException < SystemExit; end
|
141
|
+
end
|
142
|
+
<% end -%>
|