bundler08 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ require File.join(File.dirname(__FILE__), "runtime", "dsl")
2
+ require File.join(File.dirname(__FILE__), "runtime", "dependency")
@@ -0,0 +1,365 @@
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_reader :bundle
8
+
9
+ def initialize(bundle, options)
10
+ @bundle = bundle
11
+ end
12
+
13
+ private
14
+
15
+ def process_source_gems(gems)
16
+ new_gems = Hash.new { |h,k| h[k] = [] }
17
+ gems.values.each do |spec|
18
+ spec.source = self
19
+ new_gems[spec.name] << spec
20
+ end
21
+ new_gems
22
+ end
23
+ end
24
+
25
+ class GemSource < Source
26
+ attr_reader :uri
27
+
28
+ def initialize(bundle, options)
29
+ super
30
+ @uri = options[:uri]
31
+ @uri = URI.parse(@uri) unless @uri.is_a?(URI)
32
+ raise ArgumentError, "The source must be an absolute URI" unless @uri.absolute?
33
+ end
34
+
35
+ def local?
36
+ false
37
+ end
38
+
39
+ def gems
40
+ @specs ||= fetch_specs
41
+ end
42
+
43
+ def ==(other)
44
+ uri == other.uri
45
+ end
46
+
47
+ def to_s
48
+ @uri.to_s
49
+ end
50
+
51
+ class RubygemsRetardation < StandardError; end
52
+
53
+ def download(spec)
54
+ Bundler.logger.info "Downloading #{spec.full_name}.gem"
55
+
56
+ destination = bundle.gem_path
57
+
58
+ unless destination.writable?
59
+ raise RubygemsRetardation, "destination: #{destination} is not writable"
60
+ end
61
+
62
+ # Download the gem
63
+ Gem::RemoteFetcher.fetcher.download(spec, uri, destination)
64
+
65
+ # Re-read the gemspec from the downloaded gem to correct
66
+ # any errors that were present in the Rubyforge specification.
67
+ new_spec = Gem::Format.from_file_by_path(destination.join('cache', "#{spec.full_name}.gem")).spec
68
+ spec.__swap__(new_spec)
69
+ end
70
+
71
+ private
72
+
73
+ def fetch_specs
74
+ Bundler.logger.info "Updating source: #{to_s}"
75
+ build_gem_index(fetch_main_specs + fetch_prerelease_specs)
76
+ end
77
+
78
+ def build_gem_index(index)
79
+ gems = Hash.new { |h,k| h[k] = [] }
80
+ index.each do |name, version, platform|
81
+ spec = RemoteSpecification.new(name, version, platform, @uri)
82
+ spec.source = self
83
+ gems[spec.name] << spec if Gem::Platform.match(spec.platform)
84
+ end
85
+ gems
86
+ end
87
+
88
+ def fetch_main_specs
89
+ Marshal.load(Gem::RemoteFetcher.fetcher.fetch_path("#{uri}/specs.4.8.gz"))
90
+ rescue Gem::RemoteFetcher::FetchError => e
91
+ raise ArgumentError, "#{to_s} is not a valid source: #{e.message}"
92
+ end
93
+
94
+ def fetch_prerelease_specs
95
+ Marshal.load(Gem::RemoteFetcher.fetcher.fetch_path("#{uri}/prerelease_specs.4.8.gz"))
96
+ rescue Gem::RemoteFetcher::FetchError
97
+ Bundler.logger.warn "Source '#{uri}' does not support prerelease gems"
98
+ []
99
+ end
100
+ end
101
+
102
+ class SystemGemSource < Source
103
+
104
+ def self.instance
105
+ @instance
106
+ end
107
+
108
+ def self.new(*args)
109
+ @instance ||= super
110
+ end
111
+
112
+ def initialize(bundle, options = {})
113
+ super
114
+ @source = Gem::SourceIndex.from_installed_gems
115
+ end
116
+
117
+ def local?
118
+ false
119
+ end
120
+
121
+ def gems
122
+ @gems ||= process_source_gems(@source.gems)
123
+ end
124
+
125
+ def ==(other)
126
+ other.is_a?(SystemGemSource)
127
+ end
128
+
129
+ def to_s
130
+ "system"
131
+ end
132
+
133
+ def download(spec)
134
+ gemfile = Pathname.new(spec.loaded_from)
135
+ gemfile = gemfile.dirname.join('..', 'cache', "#{spec.full_name}.gem")
136
+ bundle.cache(gemfile)
137
+ end
138
+
139
+ private
140
+
141
+ end
142
+
143
+ class GemDirectorySource < Source
144
+ attr_reader :location
145
+
146
+ def initialize(bundle, options)
147
+ super
148
+ @location = options[:location]
149
+ end
150
+
151
+ def local?
152
+ true
153
+ end
154
+
155
+ def gems
156
+ @specs ||= fetch_specs
157
+ end
158
+
159
+ def ==(other)
160
+ location == other.location
161
+ end
162
+
163
+ def to_s
164
+ location.to_s
165
+ end
166
+
167
+ def download(spec)
168
+ # raise NotImplementedError
169
+ end
170
+
171
+ private
172
+
173
+ def fetch_specs
174
+ specs = Hash.new { |h,k| h[k] = [] }
175
+
176
+ Dir["#{@location}/*.gem"].each do |gemfile|
177
+ spec = Gem::Format.from_file_by_path(gemfile).spec
178
+ spec.source = self
179
+ specs[spec.name] << spec
180
+ end
181
+
182
+ specs
183
+ end
184
+ end
185
+
186
+ class DirectorySource < Source
187
+ attr_reader :location, :specs, :required_specs
188
+
189
+ def initialize(bundle, options)
190
+ super
191
+ if options[:location]
192
+ @location = Pathname.new(options[:location]).expand_path
193
+ end
194
+ @glob = options[:glob] || "**/*.gemspec"
195
+ @specs = {}
196
+ @required_specs = []
197
+ end
198
+
199
+ def add_spec(path, name, version, require_paths = %w(lib))
200
+ raise DirectorySourceError, "already have a gem defined for '#{path}'" if @specs[path.to_s]
201
+ @specs[path.to_s] = Gem::Specification.new do |s|
202
+ s.name = name
203
+ s.version = Gem::Version.new(version)
204
+ end
205
+ end
206
+
207
+ def local?
208
+ true
209
+ end
210
+
211
+ def gems
212
+ @gems ||= begin
213
+ # Locate all gemspecs from the directory
214
+ specs = locate_gemspecs
215
+ specs = merge_defined_specs(specs)
216
+
217
+ required_specs.each do |required|
218
+ unless specs.any? {|k,v| v.name == required }
219
+ raise DirectorySourceError, "No gemspec for '#{required}' was found in" \
220
+ " '#{location}'. Please explicitly specify a version."
221
+ end
222
+ end
223
+
224
+ process_source_gems(specs)
225
+ end
226
+ end
227
+
228
+ def locate_gemspecs
229
+ Dir["#{location}/#{@glob}"].inject({}) do |specs, file|
230
+ file = Pathname.new(file)
231
+ if spec = eval(File.read(file)) # and validate_gemspec(file.dirname, spec)
232
+ spec.location = file.dirname.expand_path
233
+ specs[spec.full_name] = spec
234
+ end
235
+ specs
236
+ end
237
+ end
238
+
239
+ def merge_defined_specs(specs)
240
+ @specs.each do |path, spec|
241
+ # Set the spec location
242
+ spec.location = "#{location}/#{path}"
243
+
244
+ if existing = specs.values.find { |s| s.name == spec.name }
245
+ if existing.version != spec.version
246
+ raise DirectorySourceError, "The version you specified for #{spec.name}" \
247
+ " is #{spec.version}. The gemspec is #{existing.version}."
248
+ # Not sure if this is needed
249
+ # ====
250
+ # elsif File.expand_path(existing.location) != File.expand_path(spec.location)
251
+ # raise DirectorySourceError, "The location you specified for #{spec.name}" \
252
+ # " is '#{spec.location}'. The gemspec was found at '#{existing.location}'."
253
+ end
254
+ # elsif !validate_gemspec(spec.location, spec)
255
+ # raise "Your gem definition is not valid: #{spec}"
256
+ else
257
+ specs[spec.full_name] = spec
258
+ end
259
+ end
260
+ specs
261
+ end
262
+
263
+ def validate_gemspec(path, spec)
264
+ path = Pathname.new(path)
265
+ msg = "Gemspec for #{spec.name} (#{spec.version}) is invalid:"
266
+ # Check the require_paths
267
+ (spec.require_paths || []).each do |require_path|
268
+ unless path.join(require_path).directory?
269
+ Bundler.logger.warn "#{msg} Missing require path: '#{require_path}'"
270
+ return false
271
+ end
272
+ end
273
+
274
+ # Check the executables
275
+ (spec.executables || []).each do |exec|
276
+ unless path.join(spec.bindir, exec).file?
277
+ Bundler.logger.warn "#{msg} Missing executable: '#{File.join(spec.bindir, exec)}'"
278
+ return false
279
+ end
280
+ end
281
+
282
+ true
283
+ end
284
+
285
+ def ==(other)
286
+ # TMP HAX
287
+ other.is_a?(DirectorySource)
288
+ end
289
+
290
+ def to_s
291
+ "directory: '#{location}'"
292
+ end
293
+
294
+ def download(spec)
295
+ # Nothing needed here
296
+ end
297
+ end
298
+
299
+ class GitSource < DirectorySource
300
+ attr_reader :ref, :uri, :branch
301
+
302
+ def initialize(bundle, options)
303
+ super
304
+ @uri = options[:uri]
305
+ @branch = options[:branch] || 'master'
306
+ @ref = options[:ref] || "origin/#{@branch}"
307
+ end
308
+
309
+ def local?
310
+ raise SourceNotCached, "Git repository '#{@uri}' has not been cloned yet" unless location.directory?
311
+ super
312
+ end
313
+
314
+ def location
315
+ # TMP HAX to get the *.gemspec reading to work
316
+ bundle.gem_path.join('dirs', File.basename(@uri, '.git'))
317
+ end
318
+
319
+ def gems
320
+ update if Bundler.remote?
321
+ checkout if Bundler.writable?
322
+ super
323
+ end
324
+
325
+ def download(spec)
326
+ # Nothing needed here
327
+ end
328
+
329
+ def to_s
330
+ "git: #{uri}"
331
+ end
332
+
333
+ private
334
+ def update
335
+ if location.directory?
336
+ fetch if current_revision != revision_for_ref
337
+ else
338
+ clone
339
+ end
340
+ end
341
+
342
+ def fetch
343
+ Bundler.logger.info "Fetching git repository at: #{@uri}"
344
+ Dir.chdir(location) { `git fetch origin` }
345
+ end
346
+
347
+ def clone
348
+ Bundler.logger.info "Cloning git repository at: #{@uri}"
349
+ FileUtils.mkdir_p(location.dirname)
350
+ `git clone #{@uri} #{location} --no-hardlinks`
351
+ end
352
+
353
+ def current_revision
354
+ Dir.chdir(location) { `git rev-parse HEAD`.strip }
355
+ end
356
+
357
+ def revision_for_ref
358
+ Dir.chdir(location) { `git rev-parse #{@ref}`.strip }
359
+ end
360
+
361
+ def checkout
362
+ Dir.chdir(location) { `git checkout --quiet #{@ref}` }
363
+ end
364
+ end
365
+ end
@@ -0,0 +1,72 @@
1
+ # Specify a dependency on rails. When the bundler downloads gems,
2
+ # it will download rails as well as all of rails' dependencies (such as
3
+ # activerecord, actionpack, etc...)
4
+ #
5
+ # At least one dependency must be specified
6
+ #gem "rails"
7
+
8
+ # Specify a dependency on rack v.1.0.0. The version is optional. If present,
9
+ # it can be specified the same way as with rubygems' #gem method.
10
+ #gem "rack", "1.0.0"
11
+
12
+ # Specify a dependency rspec, but only require that gem in the "testing"
13
+ # environment. :except is also a valid option to specify environment
14
+ # restrictions.
15
+ #gem "rspec", :only => :testing
16
+
17
+ # Specify a dependency, but specify that it is already present and expanded
18
+ # at vendor/rspec. Bundler will treat rspec as though it was the rspec gem
19
+ # for the purpose of gem resolution: if another gem depends on a version
20
+ # of rspec satisfied by "1.1.6", it will be used.
21
+ #
22
+ # If a gemspec is found in the directory, it will be used to specify load
23
+ # paths and supply additional dependencies.
24
+ #
25
+ # Bundler will also recursively search for *.gemspec, and assume that
26
+ # gemspecs it finds represent gems that are rooted in the same directory
27
+ # the gemspec is found in.
28
+ #gem "rspec", "1.1.6", :vendored_at => "vendor/rspec"
29
+
30
+ # You can also control what will happen when you run Bundler.require_env
31
+ # by using the :require_as option, as per the next two examples.
32
+
33
+ # Don't auto-require this gem.
34
+ #gem "rspec-rails", "1.2.9", :require_as => nil
35
+
36
+ # Require something other than the default.
37
+ #gem "yajl-ruby", "0.6.7", :require_as => "yajl/json_gem"
38
+
39
+ # Works exactly like :vendored_at, but first downloads the repo from
40
+ # git and handles stashing the files for you. As with :vendored_at,
41
+ # Bundler will automatically use *.gemspec files in the root or anywhere
42
+ # in the repository.
43
+ #gem "rails", "3.0.pre", :git => "git://github.com/rails/rails.git"
44
+
45
+ # Add http://gems.github.com as a source that the bundler will use
46
+ # to find gems listed in the manifest. By default,
47
+ # http://gems.rubyforge.org is already added to the list.
48
+ #
49
+ # This is an optional setting.
50
+ #source "http://gems.github.com"
51
+
52
+ # Specify where the bundled gems should be stashed. This directory will
53
+ # be a gem repository where all gems are downloaded to and installed to.
54
+ #
55
+ # This is an optional setting.
56
+ # The default is: vendor/gems
57
+ #bundle_path "my/bundled/gems"
58
+
59
+ # Specify where gem executables should be copied to.
60
+ #
61
+ # This is an optional setting.
62
+ # The default is: bin
63
+ #bin_path "my/executables"
64
+
65
+ # Specify that rubygems should be completely disabled. This means that it
66
+ # will be impossible to require it and that available gems will be
67
+ # limited exclusively to gems that have been bundled.
68
+ #
69
+ # The default is to automatically require rubygems. There is also a
70
+ # `disable_system_gems` option that will limit available rubygems to
71
+ # the ones that have been bundled.
72
+ #disable_rubygems
@@ -0,0 +1,3 @@
1
+ <%= shebang bin_file_name %>
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "<%= path.join("environment").relative_path_from(Pathname.new(bin_dir)) %>"))
3
+ load File.expand_path(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,156 @@
1
+ # DO NOT MODIFY THIS FILE
2
+ module Bundler
3
+ file = File.expand_path(__FILE__)
4
+ dir = File.dirname(file)
5
+
6
+ <% unless system_gems? -%>
7
+ ENV["GEM_HOME"] = dir
8
+ ENV["GEM_PATH"] = dir
9
+
10
+ # handle 1.9 where system gems are always on the load path
11
+ if defined?(::Gem)
12
+ $LOAD_PATH.reject! do |p|
13
+ p != File.dirname(__FILE__) &&
14
+ Gem.path.any? { |gp| p.include?(gp) }
15
+ end
16
+ end
17
+
18
+ <% end -%>
19
+ ENV["PATH"] = "#{dir}/<%= bindir %><%= File::PATH_SEPARATOR %>#{ENV["PATH"]}"
20
+ ENV["RUBYOPT"] = "-r#{file} #{ENV["RUBYOPT"]}"
21
+
22
+ <% load_paths.each do |load_path| -%>
23
+ $LOAD_PATH.unshift File.expand_path("#{dir}/<%= load_path %>")
24
+ <% end -%>
25
+
26
+ @gemfile = "#{dir}/<%= filename %>"
27
+
28
+ <% if rubygems? -%>
29
+ require "rubygems" unless respond_to?(:gem) # 1.9 already has RubyGems loaded
30
+
31
+ @bundled_specs = {}
32
+ <% specs.each do |spec| -%>
33
+ <% if spec.no_bundle? -%>
34
+ gem "<%= spec.name %>", "<%= spec.version %>"
35
+ <% else -%>
36
+ <% path = spec_file_for(spec) -%>
37
+ @bundled_specs["<%= spec.name %>"] = eval(File.read("#{dir}/<%= path %>"))
38
+ @bundled_specs["<%= spec.name %>"].loaded_from = "#{dir}/<%= path %>"
39
+ <% end -%>
40
+ <% end -%>
41
+
42
+ def self.add_specs_to_loaded_specs
43
+ Gem.loaded_specs.merge! @bundled_specs
44
+ end
45
+
46
+ def self.add_specs_to_index
47
+ @bundled_specs.each do |name, spec|
48
+ Gem.source_index.add_spec spec
49
+ end
50
+ end
51
+
52
+ add_specs_to_loaded_specs
53
+ add_specs_to_index
54
+ <% end -%>
55
+
56
+ def self.require_env(env = nil)
57
+ context = Class.new do
58
+ def initialize(env) @env = env && env.to_s ; end
59
+ def method_missing(*) ; yield if block_given? ; end
60
+ def only(*env)
61
+ old, @only = @only, _combine_only(env.flatten)
62
+ yield
63
+ @only = old
64
+ end
65
+ def except(*env)
66
+ old, @except = @except, _combine_except(env.flatten)
67
+ yield
68
+ @except = old
69
+ end
70
+ def gem(name, *args)
71
+ opt = args.last.is_a?(Hash) ? args.pop : {}
72
+ only = _combine_only(opt[:only] || opt["only"])
73
+ except = _combine_except(opt[:except] || opt["except"])
74
+ files = opt[:require_as] || opt["require_as"] || name
75
+ files = [files] unless files.respond_to?(:each)
76
+
77
+ return unless !only || only.any? {|e| e == @env }
78
+ return if except && except.any? {|e| e == @env }
79
+
80
+ if files = opt[:require_as] || opt["require_as"]
81
+ files = Array(files)
82
+ files.each { |f| require f }
83
+ else
84
+ begin
85
+ require name
86
+ rescue LoadError
87
+ # Do nothing
88
+ end
89
+ end
90
+ yield if block_given?
91
+ true
92
+ end
93
+ private
94
+ def _combine_only(only)
95
+ return @only unless only
96
+ only = [only].flatten.compact.uniq.map { |o| o.to_s }
97
+ only &= @only if @only
98
+ only
99
+ end
100
+ def _combine_except(except)
101
+ return @except unless except
102
+ except = [except].flatten.compact.uniq.map { |o| o.to_s }
103
+ except |= @except if @except
104
+ except
105
+ end
106
+ end
107
+ context.new(env && env.to_s).instance_eval(File.read(@gemfile), @gemfile, 1)
108
+ end
109
+ end
110
+
111
+ <% if rubygems? -%>
112
+ module Gem
113
+ @loaded_stacks = Hash.new { |h,k| h[k] = [] }
114
+
115
+ def source_index.refresh!
116
+ super
117
+ Bundler.add_specs_to_index
118
+ end
119
+ end
120
+ <% else -%>
121
+ $" << "rubygems.rb"
122
+
123
+ module Kernel
124
+ def gem(*)
125
+ # Silently ignore calls to gem, since, in theory, everything
126
+ # is activated correctly already.
127
+ end
128
+ end
129
+
130
+ # Define all the Gem errors for gems that reference them.
131
+ module Gem
132
+ def self.ruby ; <%= Gem.ruby.inspect %> ; end
133
+ def self.dir ; @dir ||= File.dirname(File.expand_path(__FILE__)) ; end
134
+ class << self ; alias default_dir dir; alias path dir ; end
135
+ class LoadError < ::LoadError; end
136
+ class Exception < RuntimeError; end
137
+ class CommandLineError < Exception; end
138
+ class DependencyError < Exception; end
139
+ class DependencyRemovalException < Exception; end
140
+ class GemNotInHomeException < Exception ; end
141
+ class DocumentError < Exception; end
142
+ class EndOfYAMLException < Exception; end
143
+ class FilePermissionError < Exception; end
144
+ class FormatException < Exception; end
145
+ class GemNotFoundException < Exception; end
146
+ class InstallError < Exception; end
147
+ class InvalidSpecificationException < Exception; end
148
+ class OperationNotSupportedError < Exception; end
149
+ class RemoteError < Exception; end
150
+ class RemoteInstallationCancelled < Exception; end
151
+ class RemoteInstallationSkipped < Exception; end
152
+ class RemoteSourceException < Exception; end
153
+ class VerificationError < Exception; end
154
+ class SystemExitException < SystemExit; end
155
+ end
156
+ <% end -%>