bundler 0.9.7 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

data/README.markdown CHANGED
@@ -30,13 +30,11 @@ root directory of your application. This can quickly be done by running
30
30
  ### Gemfile
31
31
 
32
32
  This is where you specify all of your application's dependencies. The
33
- following is an example. For more information, refer to
34
- Bundler::Dsl.
33
+ following is an example. For more information, refer to Bundler::Dsl.
35
34
 
36
- # Add :gemcutter as a source that Bundler will use
37
- # to find gems listed in the manifest. At least one source
38
- # should be listed. URLs maybe also be used, such as
39
- # http://gems.github.com.
35
+ # Add :gemcutter as a source that Bundler will use to find gems listed
36
+ # in the manifest. At least one source should be listed. URLs may also
37
+ # be used, such as http://gems.github.com.
40
38
  #
41
39
  source :gemcutter
42
40
 
@@ -54,11 +52,11 @@ Bundler::Dsl.
54
52
  #
55
53
  gem "rack", "1.0.0"
56
54
 
57
- # Add a git repository as a source, and add a dependency on a gem
58
- # from it
55
+ # Add a git repository as a source. Valid options include :branch, :tag,
56
+ # and :ref. Next, add any gems that you want from that repo.
57
+ #
59
58
  git "git://github.com/indirect/rails3-generators.git"
60
59
  gem "rails3-generators"
61
-
62
60
 
63
61
  ### Groups
64
62
 
@@ -91,7 +89,7 @@ Groups are involved in a number of scenarios:
91
89
  included.
92
90
  3. When auto-requiring files using Bundler.require, Bundler will,
93
91
  by default, auto-require just the `:default` group. You can specify
94
- a list of groups to auto-require such as
92
+ a list of groups to auto-require such as
95
93
  `Bundler.require(:default, :test)`
96
94
 
97
95
  ### Installing gems
@@ -106,6 +104,10 @@ Gems that are already installed into the system RubyGems repository will be
106
104
  referenced, rather than installed again. Every time an update is made to the
107
105
  Gemfile, run `bundle install` again to install any newly needed gems.
108
106
 
107
+ If you want to install the gems into the project's folder, like Bundler 0.8
108
+ and earlier did, you can run `bundle install vendor`, and the gems will
109
+ be installed into the `vendor` subdirectory of your project.
110
+
109
111
  ### Locking dependencies
110
112
 
111
113
  By default, bundler will only ensure that the activated gems satisfy the
@@ -116,10 +118,15 @@ The command `bundle lock` will lock the bundle to the current set of
116
118
  resolved gems. This ensures that, until the lock file is removed,
117
119
  `bundle install` and `Bundle.setup` will always activate the same gems.
118
120
 
119
- When you are distributing your application, you should add the Gemfile.lock
120
- file to your source control, so that the set of libraries your code will
121
- run against are fixed. Simply run `bundle install` after checking out or
122
- deploying your code to ensure your libraries are present.
121
+ When you are distributing your application, you should add the Gemfile and
122
+ Gemfile.lock files to your source control, so that the set of libraries your
123
+ code will run against are fixed. Simply run `bundle install` after checking
124
+ out or deploying your code to ensure your libraries are present.
125
+
126
+ DO NOT add the .bundle directory to your source control. The files there are
127
+ internal to bundler and vary between machines. If you are using git, you can
128
+ exclude all machine-specific bundler files by adding a single line to your
129
+ .gitignore file containing `.bundle`.
123
130
 
124
131
  ### Running the application
125
132
 
@@ -137,7 +144,12 @@ To do this, include the following at the beginning of your code.
137
144
  Bundler.setup
138
145
  end
139
146
 
140
- # Your application requires come here
147
+ # Your application's requires come here, e.g.
148
+ # require 'date' # a ruby standard library
149
+ # require 'rack' # a bundled gem
150
+
151
+ # Alternatively, you can require all the bundled libs at once
152
+ # Bundler.require
141
153
 
142
154
  The `bundle exec` command provides a way to run arbitrary ruby code in
143
155
  context of the bundle. For example:
@@ -151,7 +163,7 @@ shell is).
151
163
  ### Packing the bundle's gems
152
164
 
153
165
  When sharing or deploying an application, you may want to include
154
- everything necessary to install gem dependencies. `bundle pack` will
166
+ everything necessary to install gem dependencies. `bundle package` will
155
167
  copy .gem files for all of the bundle's dependencies into vendor/cache.
156
168
  After that, `bundle install` will always work, since it will install the
157
169
  local .gem files, and will not contact any of the remote sources.
@@ -247,10 +259,10 @@ Bundler 0.9 changes the following Bundler 0.8 Gemfile APIs:
247
259
 
248
260
  ### API Changes
249
261
 
250
- 1. `Bundler.require_env(:environment)` becomes
262
+ 1. `Bundler.require_env(:environment)` becomes
251
263
  `Bundler.require(:multiple, :groups)`. You must
252
264
  now specify the default group (the default group is the
253
- group made up of the gems not assigned to any group)
265
+ group made up of the gems not assigned to any group)
254
266
  explicitly. So `Bundler.require_env(:test)` becomes
255
267
  `Bundler.require(:default, :test)`
256
268
 
@@ -269,3 +281,17 @@ Any remaining questions may be directed via email to the [Bundler mailing list](
269
281
  ## Reporting bugs
270
282
 
271
283
  Please report all bugs on the github issue tracker for the project, located at [http://github.com/carlhuda/bundler/issues/](http://github.com/carlhuda/bundler/issues/).
284
+
285
+ The best possible scenario is a ticket with a fix for the bug and a test for the fix. If that's not possible, instructions to reproduce the issue are vitally important. If you're not sure exactly how to reproduce the issue that you are seeing, create a gist of the following information and include it in your ticket:
286
+
287
+ - Whether you have locked or not
288
+ - What version of bundler you are using
289
+ - Your Gemfile
290
+ - The command you ran to generate exception(s)
291
+ - The exception backtrace(s)
292
+
293
+ If you are using Rails 2.3, please also include:
294
+
295
+ - Your boot.rb file
296
+ - Your preinitializer.rb file
297
+ - Your environment.rb file
data/lib/bundler.rb CHANGED
@@ -1,10 +1,10 @@
1
1
  require 'fileutils'
2
2
  require 'pathname'
3
3
  require 'yaml'
4
- require 'bundler/rubygems-ext'
4
+ require 'bundler/rubygems_ext'
5
5
 
6
6
  module Bundler
7
- VERSION = "0.9.7"
7
+ VERSION = "0.9.8"
8
8
 
9
9
  autoload :Definition, 'bundler/definition'
10
10
  autoload :Dependency, 'bundler/dependency'
data/lib/bundler/cli.rb CHANGED
@@ -53,6 +53,7 @@ module Bundler
53
53
 
54
54
  Bundler.settings[:path] = path if path
55
55
  Bundler.settings[:disable_shared_gems] = '1' if options["disable-shared-gems"]
56
+ Bundler.settings.without = opts[:without]
56
57
 
57
58
  remove_lockfiles if options[:relock]
58
59
 
@@ -98,11 +99,22 @@ module Bundler
98
99
  end
99
100
  end
100
101
 
101
- desc "pack", "Packs all the gems to vendor/cache"
102
- def pack
102
+ desc "cache", "Cache all the gems to vendor/cache"
103
+ def cache
103
104
  environment = Bundler.load
104
- environment.pack
105
+ environment.cache
106
+ rescue GemNotFound => e
107
+ Bundler.ui.error(e.message)
108
+ Bundler.ui.info "Run `bundle install` to install missing gems."
109
+ exit 128
110
+ end
111
+
112
+ desc "package", "Locks and then caches all of the gems into vendor/cache"
113
+ def package
114
+ lock
115
+ cache
105
116
  end
117
+ map %w(pack) => :package
106
118
 
107
119
  desc "exec", "Run the command in context of the bundle"
108
120
  def exec(*)
@@ -142,5 +154,12 @@ module Bundler
142
154
  FileUtils.rm_f "#{Bundler.root}/Gemfile.lock"
143
155
  FileUtils.rm_f "#{Bundler.root}/.bundle/environment.rb"
144
156
  end
157
+
158
+ def self.printable_tasks
159
+ tasks = super.dup
160
+ tasks.reject!{|t| t.first =~ /cache/ }
161
+ tasks
162
+ end
163
+
145
164
  end
146
165
  end
@@ -13,10 +13,8 @@ module Bundler
13
13
  end
14
14
 
15
15
  def self.from_lock(lockfile)
16
- # gemfile_definition = from_gemfile(nil)
17
16
  locked_definition = Locked.new(YAML.load_file(lockfile))
18
17
 
19
- # TODO: Switch to using equivalent?
20
18
  hash = Digest::SHA1.hexdigest(File.read("#{Bundler.root}/Gemfile"))
21
19
  unless locked_definition.hash == hash
22
20
  raise GemfileError, "You changed your Gemfile after locking. Please relock using `bundle lock`"
@@ -43,20 +41,14 @@ module Bundler
43
41
  index = source.local_specs.merge(index)
44
42
  end
45
43
 
46
- Index.from_installed_gems.merge(index)
44
+ index = Index.from_installed_gems.merge(index)
45
+ Index.from_cached_specs("#{Bundler.bundle_path}/cache").merge(index)
47
46
  end
48
47
  end
49
48
 
50
- # def equivalent?(other)
51
- # self.matches?(other) && other.matches?(self)
52
- # # other.matches?(self)
53
- # end
54
-
55
- # def matches?(other)
56
- # dependencies.all? do |dep|
57
- # dep =~ other.specs.find {|spec| spec.name == dep.name }
58
- # end
59
- # end
49
+ def groups
50
+ dependencies.map { |d| d.groups }.flatten.uniq
51
+ end
60
52
 
61
53
  class Locked < Definition
62
54
  def initialize(details)
data/lib/bundler/dsl.rb CHANGED
@@ -9,6 +9,7 @@ module Bundler
9
9
  end
10
10
 
11
11
  def initialize
12
+ @source = nil
12
13
  @sources = []
13
14
  @dependencies = []
14
15
  @group = nil
@@ -28,22 +29,26 @@ module Bundler
28
29
  end
29
30
 
30
31
  def source(source, options = {})
31
- source = case source
32
+ @source = case source
32
33
  when :gemcutter, :rubygems, :rubyforge then Source::Rubygems.new("uri" => "http://gemcutter.org")
33
34
  when String then Source::Rubygems.new("uri" => source)
34
35
  else source
35
36
  end
36
37
 
37
- options[:prepend] ? @sources.unshift(source) : @sources << source
38
- source
38
+ options[:prepend] ? @sources.unshift(@source) : @sources << @source
39
+
40
+ yield if block_given?
41
+ @source
42
+ ensure
43
+ @source = nil
39
44
  end
40
45
 
41
- def path(path, options = {}, source_options = {})
42
- source Source::Path.new(_normalize_hash(options).merge("path" => path)), source_options
46
+ def path(path, options = {}, source_options = {}, &blk)
47
+ source Source::Path.new(_normalize_hash(options).merge("path" => Pathname.new(path))), source_options, &blk
43
48
  end
44
49
 
45
- def git(uri, options = {}, source_options = {})
46
- source Source::Git.new(_normalize_hash(options).merge("uri" => uri)), source_options
50
+ def git(uri, options = {}, source_options = {}, &blk)
51
+ source Source::Git.new(_normalize_hash(options).merge("uri" => uri)), source_options, &blk
47
52
  end
48
53
 
49
54
  def to_definition
@@ -98,12 +103,14 @@ module Bundler
98
103
  # Normalize git and path options
99
104
  ["git", "path"].each do |type|
100
105
  if param = opts[type]
101
- source = send(type, param, opts.dup, :prepend => true)
102
- source.default_spec name, version if _version?(version)
106
+ options = _version?(version) ? opts.merge("name" => name, "version" => version) : opts.dup
107
+ source = send(type, param, options, :prepend => true)
103
108
  opts["source"] = source
104
109
  end
105
110
  end
106
111
 
112
+ opts["source"] ||= @source
113
+
107
114
  opts["group"] = group
108
115
  end
109
116
 
data/lib/bundler/index.rb CHANGED
@@ -4,6 +4,17 @@ module Bundler
4
4
  Source::SystemGems.new.specs
5
5
  end
6
6
 
7
+ def self.from_cached_specs(path)
8
+ index = Index.new
9
+
10
+ Dir["#{path}/*.gem"].each do |gemfile|
11
+ spec = Gem::Format.from_file_by_path(gemfile).spec
12
+ index << spec
13
+ end
14
+
15
+ index
16
+ end
17
+
7
18
  def initialize
8
19
  @cache = {}
9
20
  @specs = Hash.new { |h,k| h[k] = [] }
@@ -76,7 +87,7 @@ module Bundler
76
87
  @cache[dependency.hash] ||= begin
77
88
  specs = @specs[dependency.name]
78
89
 
79
- wants_prerelease = dependency.version_requirements.prerelease?
90
+ wants_prerelease = dependency.requirement.prerelease?
80
91
  only_prerelease = specs.all? {|spec| spec.version.prerelease? }
81
92
  found = specs.select { |spec| dependency =~ spec }
82
93
 
@@ -16,7 +16,9 @@ module Bundler
16
16
  FileUtils.mkdir_p(Bundler.bundle_path)
17
17
 
18
18
  specs.sort_by { |s| s.name }.each do |spec|
19
- if (spec.groups & options[:without]).any?
19
+ spec.source.fetch(spec) if spec.source.respond_to?(:fetch)
20
+
21
+ if spec.groups & Bundler.settings.without == spec.groups
20
22
  Bundler.ui.debug " * Not in requested group; skipping."
21
23
  next
22
24
  end
@@ -81,7 +83,7 @@ module Bundler
81
83
  end
82
84
 
83
85
  def ambiguous?(dep)
84
- dep.version_requirements.requirements.any? { |op,_| op != '=' }
86
+ dep.requirement.requirements.any? { |op,_| op != '=' }
85
87
  end
86
88
 
87
89
  def index
@@ -1,3 +1,6 @@
1
+ require "uri"
2
+ require "rubygems/spec_fetcher"
3
+
1
4
  module Bundler
2
5
  # Represents a lazily loaded gem specification, where the full specification
3
6
  # is on the source server in rubygems' "quick" index. The proxy object is to
@@ -40,9 +43,7 @@ module Bundler
40
43
 
41
44
  def _remote_specification
42
45
  @specification ||= begin
43
- deflated = Gem::RemoteFetcher.fetcher.fetch_path(_remote_uri)
44
- inflated = Gem.inflate(deflated)
45
- Marshal.load(inflated)
46
+ Gem::SpecFetcher.new.fetch_spec([@name, @version, @platform], URI(@source_uri.to_s))
46
47
  end
47
48
  end
48
49
 
@@ -94,24 +94,24 @@ module Bundler
94
94
  # 3) Sort by number of gems available in the source.
95
95
  reqs = reqs.sort_by do |a|
96
96
  [ activated[a.name] ? 0 : 1,
97
- a.version_requirements.prerelease? ? 0 : 1,
97
+ a.requirement.prerelease? ? 0 : 1,
98
98
  @errors[a.name] ? 0 : 1,
99
99
  activated[a.name] ? 0 : search(a).size ]
100
100
  end
101
101
 
102
102
  debug { "Activated:\n" + activated.values.map { |a| " #{a.name} (#{a.version})" }.join("\n") }
103
- debug { "Requirements:\n" + reqs.map { |r| " #{r.name} (#{r.version_requirements})"}.join("\n") }
103
+ debug { "Requirements:\n" + reqs.map { |r| " #{r.name} (#{r.requirement})"}.join("\n") }
104
104
 
105
105
  activated = activated.dup
106
106
  # Pull off the first requirement so that we can resolve it
107
107
  current = reqs.shift
108
108
 
109
- debug { "Attempting:\n #{current.name} (#{current.version_requirements})"}
109
+ debug { "Attempting:\n #{current.name} (#{current.requirement})"}
110
110
 
111
111
  # Check if the gem has already been activated, if it has, we will make sure
112
112
  # that the currently activated gem satisfies the requirement.
113
113
  if existing = activated[current.name]
114
- if current.version_requirements.satisfied_by?(existing.version)
114
+ if current.requirement.satisfied_by?(existing.version)
115
115
  debug { " * [SUCCESS] Already activated" }
116
116
  @errors.delete(existing.name)
117
117
  # Since the current requirement is satisfied, we can continue resolving
@@ -120,7 +120,7 @@ module Bundler
120
120
  else
121
121
  debug { " * [FAIL] Already activated" }
122
122
  @errors[existing.name] = [existing, current]
123
- debug { current.required_by.map {|d| " * #{d.name} (#{d.version_requirements})" }.join("\n") }
123
+ debug { current.required_by.map {|d| " * #{d.name} (#{d.requirement})" }.join("\n") }
124
124
  # debug { " * All current conflicts:\n" + @errors.keys.map { |c| " - #{c}" }.join("\n") }
125
125
  # Since the current requirement conflicts with an activated gem, we need
126
126
  # to backtrack to the current requirement's parent and try another version
@@ -199,14 +199,14 @@ module Bundler
199
199
 
200
200
  activated[spec.name] = spec
201
201
  debug { " Activating: #{spec.name} (#{spec.version})" }
202
- debug { spec.required_by.map { |d| " * #{d.name} (#{d.version_requirements})" }.join("\n") }
202
+ debug { spec.required_by.map { |d| " * #{d.name} (#{d.requirement})" }.join("\n") }
203
203
 
204
204
  # Now, we have to loop through all child dependencies and add them to our
205
205
  # array of requirements.
206
206
  debug { " Dependencies"}
207
207
  spec.dependencies.each do |dep|
208
208
  next if dep.type == :development
209
- debug { " * #{dep.name} (#{dep.version_requirements})" }
209
+ debug { " * #{dep.name} (#{dep.requirement})" }
210
210
  dep.required_by.replace(requirement.required_by)
211
211
  dep.required_by << requirement
212
212
  reqs << dep
@@ -12,10 +12,18 @@ module Gem
12
12
  def load_paths
13
13
  require_paths.map {|p| File.join(full_gem_path, p) }
14
14
  end
15
-
15
+
16
16
  def groups
17
17
  @groups ||= []
18
18
  end
19
+
20
+ alias_method :old_dependencies, :dependencies
21
+
22
+ def dependencies
23
+ original = old_dependencies
24
+ original << Dependency.new("rake", ">= 0") if extensions.any? { |e| e =~ /rakefile|mkrf_conf/i }
25
+ original
26
+ end
19
27
  end
20
28
 
21
29
  class Dependency
@@ -6,7 +6,7 @@ module Bundler
6
6
 
7
7
  def initialize(*)
8
8
  super
9
- if locked? # && !rb_lock_file.exist?
9
+ if locked?
10
10
  write_rb_lock
11
11
  end
12
12
  end
@@ -76,12 +76,10 @@ module Bundler
76
76
  end
77
77
 
78
78
  def specs_for(*groups)
79
+ groups = @definition.groups if groups.empty?
80
+ groups -= Bundler.settings.without
79
81
  groups.map! { |g| g.to_sym }
80
- if groups.empty?
81
- specs
82
- else
83
- Resolver.resolve(dependencies_for(*groups), index)
84
- end
82
+ specs.select { |s| (s.groups & groups).any? }
85
83
  end
86
84
 
87
85
  def specs
@@ -102,18 +100,19 @@ module Bundler
102
100
  @definition.local_index
103
101
  end
104
102
 
105
- def pack
106
- pack_path = "#{root}/vendor/cache/"
107
- FileUtils.mkdir_p(pack_path)
103
+ def cache
104
+ cache_path = "#{root}/vendor/cache/"
105
+ FileUtils.mkdir_p(cache_path)
108
106
 
109
107
  Bundler.ui.info "Copying .gem files into vendor/cache"
110
108
  specs.each do |spec|
111
109
  next unless spec.source.is_a?(Source::SystemGems) || spec.source.is_a?(Source::Rubygems)
112
110
  possibilities = Gem.path.map { |p| "#{p}/cache/#{spec.full_name}.gem" }
113
111
  cached_path = possibilities.find { |p| File.exist? p }
112
+ raise GemNotFound, "Missing gem file '#{spec.full_name}.gem'." unless cached_path
114
113
  Bundler.ui.info " * #{File.basename(cached_path)}"
115
- next if File.expand_path(File.dirname(cached_path)) == File.expand_path(pack_path)
116
- FileUtils.cp(cached_path, pack_path)
114
+ next if File.expand_path(File.dirname(cached_path)) == File.expand_path(cache_path)
115
+ FileUtils.cp(cached_path, cache_path)
117
116
  end
118
117
  end
119
118
 
@@ -160,7 +159,7 @@ module Bundler
160
159
  end
161
160
 
162
161
  details["dependencies"] = @definition.dependencies.inject({}) do |h,d|
163
- info = {"version" => d.version_requirements.to_s, "group" => d.groups}
162
+ info = {"version" => d.requirement.to_s, "group" => d.groups}
164
163
  info.merge!("require" => d.autorequire) if d.autorequire
165
164
  h.merge(d.name => info)
166
165
  end
@@ -172,7 +171,7 @@ module Bundler
172
171
  end
173
172
 
174
173
  def specs_for_lock_file
175
- specs.map do |s|
174
+ specs_for.map do |s|
176
175
  hash = {}
177
176
  hash[:loaded_from] = s.loaded_from.to_s
178
177
  hash[:load_paths] = s.load_paths
@@ -20,6 +20,14 @@ module Bundler
20
20
  value
21
21
  end
22
22
 
23
+ def without=(array)
24
+ self[:without] = array.join(":")
25
+ end
26
+
27
+ def without
28
+ self[:without] ? self[:without].split(":").map { |w| w.to_sym } : []
29
+ end
30
+
23
31
  private
24
32
 
25
33
  def config_file
@@ -1,3 +1,13 @@
1
+ module Gem
2
+ class Dependency
3
+ if !instance_methods.map { |m| m.to_s }.include?("requirement")
4
+ def requirement
5
+ version_requirements
6
+ end
7
+ end
8
+ end
9
+ end
10
+
1
11
  module Bundler
2
12
  module SharedHelpers
3
13
 
@@ -68,7 +78,7 @@ module Bundler
68
78
  end
69
79
  opts = reqs.last.is_a?(Hash) ? reqs.pop : {}
70
80
 
71
- unless dep.respond_to?(:name) && dep.respond_to?(:version_requirements)
81
+ unless dep.respond_to?(:name) && dep.respond_to?(:requirement)
72
82
  dep = Gem::Dependency.new(dep, reqs)
73
83
  end
74
84
 
@@ -77,13 +87,13 @@ module Bundler
77
87
  if spec.nil?
78
88
  e = Gem::LoadError.new "#{dep.name} is not part of the bundle. Add it to Gemfile."
79
89
  e.name = dep.name
80
- e.version_requirement = dep.version_requirements
90
+ e.version_requirement = dep.requirement
81
91
  raise e
82
92
  elsif dep !~ spec
83
93
  e = Gem::LoadError.new "can't activate #{dep}, already activated #{spec.full_name}. " \
84
94
  "Make sure all dependencies are added to Gemfile."
85
95
  e.name = dep.name
86
- e.version_requirement = dep.version_requirements
96
+ e.version_requirement = dep.requirement
87
97
  raise e
88
98
  end
89
99
 
@@ -1,4 +1,5 @@
1
- require "rubygems/remote_fetcher"
1
+ require "uri"
2
+ require "rubygems/spec_fetcher"
2
3
  require "rubygems/format"
3
4
  require "digest/sha1"
4
5
  require "open3"
@@ -10,7 +11,8 @@ module Bundler
10
11
 
11
12
  def initialize(options = {})
12
13
  @options = options
13
- @uri = options["uri"]
14
+ @uri = options["uri"].to_s
15
+ @uri = "#{uri}/" unless @uri =~ %r'/$'
14
16
  @uri = URI.parse(@uri) unless @uri.is_a?(URI)
15
17
  raise ArgumentError, "The source must be an absolute URI" unless @uri.absolute?
16
18
  end
@@ -23,13 +25,14 @@ module Bundler
23
25
  @specs ||= fetch_specs
24
26
  end
25
27
 
26
- def install(spec)
27
- destination = Gem.dir
28
-
28
+ def fetch(spec)
29
29
  Bundler.ui.debug " * Downloading"
30
- gem_path = Gem::RemoteFetcher.fetcher.download(spec, uri, destination)
30
+ Gem::RemoteFetcher.fetcher.download(spec, uri, Gem.dir)
31
+ end
32
+
33
+ def install(spec)
31
34
  Bundler.ui.debug " * Installing"
32
- installer = Gem::Installer.new gem_path,
35
+ installer = Gem::Installer.new gem_path(spec),
33
36
  :install_dir => Gem.dir,
34
37
  :ignore_dependencies => true,
35
38
  :wrappers => true,
@@ -41,29 +44,32 @@ module Bundler
41
44
 
42
45
  private
43
46
 
47
+ def gem_path(spec)
48
+ "#{Gem.dir}/cache/#{spec.full_name}.gem"
49
+ end
50
+
44
51
  def fetch_specs
45
52
  index = Index.new
46
53
  Bundler.ui.info "Fetching source index from #{uri}"
47
- (main_specs + prerelease_specs).each do |name, version, platform|
48
- next unless Gem::Platform.match(platform)
49
- spec = RemoteSpecification.new(name, version, platform, @uri)
50
- spec.source = self
51
- index << spec
54
+ old, Gem.sources = Gem.sources, ["#{uri}"]
55
+
56
+ fetch_all_specs do |n,v|
57
+ v.each do |name, version, platform|
58
+ next unless Gem::Platform.match(platform)
59
+ spec = RemoteSpecification.new(name, version, platform, @uri)
60
+ spec.source = self
61
+ index << spec
62
+ end
52
63
  end
53
- index.freeze
54
- end
55
64
 
56
- def main_specs
57
- Marshal.load(Gem::RemoteFetcher.fetcher.fetch_path("#{uri}/specs.4.8.gz"))
58
- rescue Gem::RemoteFetcher::FetchError => e
59
- raise ArgumentError, "#{to_s} is not a valid source: #{e.message}"
65
+ index.freeze
66
+ ensure
67
+ Gem.sources = old
60
68
  end
61
69
 
62
- def prerelease_specs
63
- Marshal.load(Gem::RemoteFetcher.fetcher.fetch_path("#{uri}/prerelease_specs.4.8.gz"))
64
- rescue Gem::RemoteFetcher::FetchError
65
- Bundler.ui.warn "Source '#{uri}' does not support prerelease gems"
66
- []
70
+ def fetch_all_specs(&blk)
71
+ Gem::SpecFetcher.new.list(true, false).each(&blk)
72
+ Gem::SpecFetcher.new.list(false, true).each(&blk)
67
73
  end
68
74
  end
69
75
 
@@ -72,7 +78,7 @@ module Bundler
72
78
  @specs ||= begin
73
79
  index = Index.new
74
80
 
75
- Gem::SourceIndex.from_installed_gems.each do |name, spec|
81
+ Gem::SourceIndex.from_installed_gems.reverse_each do |name, spec|
76
82
  spec.source = self
77
83
  index << spec
78
84
  end
@@ -101,22 +107,16 @@ module Bundler
101
107
 
102
108
  def specs
103
109
  @specs ||= begin
104
- index = Index.new
105
-
106
- Dir["#{@path}/*.gem"].each do |gemfile|
107
- spec = Gem::Format.from_file_by_path(gemfile).spec
108
- spec.source = self
109
- index << spec
110
- end
111
-
112
- index.freeze
110
+ specs = Index.from_cached_specs(@path)
111
+ specs.each { |s| s.source = self }
112
+ specs
113
113
  end
114
114
  end
115
115
 
116
116
  def install(spec)
117
117
  destination = Gem.dir
118
118
 
119
- Bundler.ui.debug " * Installing from pack"
119
+ Bundler.ui.debug " * Installing from cache"
120
120
  installer = Gem::Installer.new "#{@path}/#{spec.full_name}.gem",
121
121
  :install_dir => Gem.dir,
122
122
  :ignore_dependencies => true,
@@ -129,53 +129,54 @@ module Bundler
129
129
  end
130
130
 
131
131
  class Path
132
- attr_reader :path, :options
132
+ attr_reader :path, :options, :default_spec
133
133
 
134
134
  def initialize(options)
135
135
  @options = options
136
136
  @glob = options["glob"] || "{,*/}*.gemspec"
137
- @path = options["path"]
138
- @default_spec = nil
137
+
138
+ if options["path"]
139
+ @path = Pathname.new(options["path"]).expand_path(Bundler.root)
140
+ end
141
+
142
+ if options["name"]
143
+ @default_spec = Specification.new do |s|
144
+ s.name = options["name"]
145
+ s.source = self
146
+ s.version = Gem::Version.new(options["version"])
147
+ s.summary = "Fake gemspec for #{options["name"]}"
148
+ s.relative_loaded_from = "#{options["name"]}.gemspec"
149
+ end
150
+ end
139
151
  end
140
152
 
141
153
  def to_s
142
154
  "source code at #{@path}"
143
155
  end
144
156
 
145
- def default_spec(*args)
146
- return @default_spec if args.empty?
147
- name, version = *args
148
- @default_spec = Specification.new do |s|
149
- s.name = name
150
- s.source = self
151
- s.version = Gem::Version.new(version)
152
- s.relative_loaded_from = "#{name}.gemspec"
153
- end
154
- end
155
-
156
- def local_specs
157
- @local_specs ||= begin
158
- index = Index.new
157
+ def load_spec_files
158
+ index = Index.new
159
159
 
160
- if File.directory?(path)
161
- Dir["#{path}/#{@glob}"].each do |file|
162
- file = Pathname.new(file)
163
- relative_path = file.relative_path_from(Pathname.new(path))
164
- # Do it in the root of the repo in case they do
165
- # assume being in the root
166
- if spec = Dir.chdir(path) { eval(File.read(relative_path)) }
167
- spec = Specification.from_gemspec(spec)
168
- spec.loaded_from = file
169
- spec.source = self
170
- index << spec
171
- end
160
+ if File.directory?(path)
161
+ Dir["#{path}/#{@glob}"].each do |file|
162
+ file = Pathname.new(file)
163
+ # Eval the gemspec from its parent directory
164
+ if spec = Dir.chdir(file.dirname) { eval(File.read(file.basename)) }
165
+ spec = Specification.from_gemspec(spec)
166
+ spec.loaded_from = file.to_s
167
+ spec.source = self
168
+ index << spec
172
169
  end
173
-
174
- index << default_spec if default_spec && index.empty?
175
170
  end
176
171
 
177
- index.freeze
172
+ index << default_spec if default_spec && index.empty?
178
173
  end
174
+
175
+ index.freeze
176
+ end
177
+
178
+ def local_specs
179
+ @local_specs ||= load_spec_files
179
180
  end
180
181
 
181
182
  def install(spec)
@@ -188,19 +189,35 @@ module Bundler
188
189
  private
189
190
 
190
191
  def generate_bin(spec)
191
- # HAX -- Generate the bin
192
- bin_dir = "#{Gem.dir}/bin"
193
- gem_dir = spec.full_gem_path
194
- installer = Gem::Installer.allocate
195
- installer.instance_eval do
196
- @spec = spec
197
- @bin_dir = bin_dir
198
- @gem_dir = gem_dir
199
- @wrappers = true
200
- @env_shebang = false
201
- @format_executable = false
192
+ gem_dir = spec.full_gem_path
193
+ gem_file = nil # so we have access once after it's set in the block
194
+
195
+ Dir.chdir(gem_dir) do
196
+ gem_file = Gem::Builder.new(spec).build
202
197
  end
198
+
199
+ installer = Gem::Installer.new File.join(gem_dir, gem_file),
200
+ :bin_dir => "#{Gem.dir}/bin",
201
+ :wrappers => true,
202
+ :env_shebang => false,
203
+ :format_executable => false
204
+
205
+ installer.instance_eval { @gem_dir = gem_dir }
206
+
207
+ installer.build_extensions
203
208
  installer.generate_bin
209
+ rescue Gem::InvalidSpecificationException => e
210
+ Bundler.ui.warn "\n#{spec.name} at #{spec.full_gem_path} did not have a valid gemspec.\n" \
211
+ "This prevents bundler from installing bins or native extensions, but " \
212
+ "that may not affect its functionality."
213
+
214
+ if !spec.extensions.empty? && !spec.emails.empty?
215
+ Bundler.ui.warn "If you need to use this package without installing it from a gem " \
216
+ "repository, please contact #{spec.emails.join(", or ")} and ask them " \
217
+ "to modify their .gemspec so it can work with `gem build`."
218
+ end
219
+
220
+ Bundler.ui.warn "The validation message from Rubygems was:\n #{e.message}"
204
221
  end
205
222
 
206
223
  end
@@ -209,8 +226,7 @@ module Bundler
209
226
  attr_reader :uri, :ref, :options
210
227
 
211
228
  def initialize(options)
212
- @options = options
213
- @glob = options["glob"] || "{,*/}*.gemspec"
229
+ super
214
230
  @uri = options["uri"]
215
231
  @ref = options["ref"] || options["branch"] || 'master'
216
232
  end
@@ -225,33 +241,10 @@ module Bundler
225
241
  end
226
242
 
227
243
  def specs
228
- @specs ||= begin
229
- index = Index.new
230
- # Start by making sure the git cache is up to date
231
- cache
232
- # Find all gemspecs in the repo
233
- in_cache do
234
- out = %x(git ls-tree -r #{revision}).strip
235
- lines = out.split("\n").select { |l| l =~ /\.gemspec$/ }
236
- # Loop over the lines and extract the relative path and the
237
- # git hash
238
- lines.each do |line|
239
- next unless line =~ %r{^(\d+) (blob|tree) ([a-f0-9]+)\t(.*)$}
240
- hash, file = $3, $4
241
- # Read the gemspec
242
- if spec = eval(%x(git cat-file blob #{$3}))
243
- spec = Specification.from_gemspec(spec)
244
- spec.relative_loaded_from = file
245
- spec.source = self
246
- index << spec
247
- end
248
- end
249
- end
250
-
251
- index << default_spec if default_spec && index.empty?
252
-
253
- index.freeze
254
- end
244
+ # Start by making sure the git cache is up to date
245
+ cache
246
+ checkout
247
+ @specs ||= load_spec_files
255
248
  end
256
249
 
257
250
  def install(spec)
@@ -16,7 +16,7 @@ module Bundler
16
16
  end
17
17
 
18
18
  def full_gem_path
19
- loaded_from.dirname.expand_path
19
+ Pathname.new(loaded_from).dirname.expand_path
20
20
  end
21
21
  end
22
22
  end
@@ -65,7 +65,7 @@ class Thor
65
65
  else
66
66
  self[$1] == args.first
67
67
  end
68
- else
68
+ else
69
69
  self[method]
70
70
  end
71
71
  end
@@ -105,7 +105,7 @@ class Thor
105
105
  end
106
106
 
107
107
  sentence = truncate(sentence, options[:truncate]) if options[:truncate]
108
- $stdout.puts sentence
108
+ $stdout.puts sentence
109
109
  end
110
110
  end
111
111
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.7
4
+ version: 0.9.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carl Lerche
@@ -10,8 +10,8 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2010-02-17 00:00:00 -08:00
14
- default_executable:
13
+ date: 2010-02-23 00:00:00 -08:00
14
+ default_executable: bundle
15
15
  dependencies: []
16
16
 
17
17
  description:
@@ -34,7 +34,7 @@ files:
34
34
  - lib/bundler/installer.rb
35
35
  - lib/bundler/remote_specification.rb
36
36
  - lib/bundler/resolver.rb
37
- - lib/bundler/rubygems-ext.rb
37
+ - lib/bundler/rubygems_ext.rb
38
38
  - lib/bundler/runtime.rb
39
39
  - lib/bundler/settings.rb
40
40
  - lib/bundler/setup.rb
@@ -69,7 +69,10 @@ has_rdoc: true
69
69
  homepage: http://github.com/carlhuda/bundler
70
70
  licenses: []
71
71
 
72
- post_install_message: Due to a rubygems bug, you must uninstall all older versions of bundler for 0.9 to work
72
+ post_install_message: |
73
+ Due to a rubygems bug, you must uninstall older versions of the bundler gem for 0.9 to work.
74
+ If you still need bundler 0.8, install the 'bundler08' gem.
75
+
73
76
  rdoc_options: []
74
77
 
75
78
  require_paths: