bundler 0.9.11 → 0.9.12

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.

@@ -0,0 +1,109 @@
1
+ ## 0.9.12 (???)
2
+
3
+ Bugfixes:
4
+
5
+ - perform a topological sort on resolved gems (#191)
6
+
7
+ ## 0.9.11 (March 9, 2010)
8
+
9
+ - added roadmap with future development plans
10
+
11
+ Features:
12
+
13
+ - install command can take the path to the gemfile with --gemfile (#125)
14
+ - unknown command line options are now rejected (#163)
15
+ - exec command hugely sped up while locked (#177)
16
+ - show command prints the install path if you pass it a gem name (#148)
17
+ - open command edits an installed gem with $EDITOR (#148)
18
+ - Gemfile allows assigning an array of groups to a gem (#114)
19
+ - Gemfile allows :tag option on :git sources
20
+ - improve backtraces when a gemspec is invalid
21
+ - improve performance by installing gems from the cache if present
22
+
23
+ Bugfixes:
24
+
25
+ - normalize parameters to Bundler.require (#153)
26
+ - check now checks installed gems rather than cached gems (#162)
27
+ - don't update the gem index when installing after locking (#169)
28
+ - bundle parenthesises arguments for 1.8.6 (#179)
29
+ - gems can now be assigned to multiple groups without problems (#135)
30
+ - fix the warning when building extensions for a gem from git with Rubygems 1.3.6
31
+ - fix a Dependency.to_yaml error due to accidentally including sources and groups
32
+ - don't reinstall packed gems
33
+ - fix gems with git sources that are private repositories
34
+
35
+ ## 0.9.10 (March 1, 2010)
36
+
37
+ - depends on Rubygems 1.3.6
38
+
39
+ Bugfixes:
40
+
41
+ - support locking after install --without
42
+ - don't reinstall gems from the cache if they're already in the bundle
43
+ - fixes for Ruby 1.8.7 and 1.9
44
+
45
+ ## 0.9.9 (February 25, 2010)
46
+
47
+ Bugfixes:
48
+
49
+ - don't die if GEM_HOME is an empty string
50
+ - fixes for Ruby 1.8.6 and 1.9
51
+
52
+ ## 0.9.8 (February 23, 2010)
53
+
54
+ Features:
55
+
56
+ - pack command which both caches and locks
57
+ - descriptive error if a cached gem is missing
58
+ - remember the --without option after installing
59
+ - expand paths given in the Gemfile via the :path option
60
+ - add block syntax to the git and group options in the Gemfile
61
+ - support gems with extensions that don't admit they depend on rake
62
+ - generate gems using gem build gemspec so git gems can have native extensions
63
+ - print a useful warning if building a gem fails
64
+ - allow manual configuration via BUNDLE_PATH
65
+
66
+ Bugfixes:
67
+
68
+ - eval gemspecs in the gem directory so relative paths work
69
+ - make default spec for git sources valid
70
+ - don't reinstall gems that are already packed
71
+
72
+ ## 0.9.7 (February 17, 2010)
73
+
74
+ Bugfixes:
75
+
76
+ - don't say that a gem from an excluded group is "installing"
77
+ - improve crippling rubygems in locked scenarios
78
+
79
+ ## 0.9.6 (February 16, 2010)
80
+
81
+ Features:
82
+
83
+ - allow String group names
84
+ - a number of improvements in the documentation and error messages
85
+
86
+ Bugfixes:
87
+
88
+ - set SourceIndex#spec_dirs to solve a problem involving Rails 2.3 in unlocked mode
89
+ - ensure Rubygems is fully loaded in Ruby 1.9 before patching it
90
+ - fix `bundle install` for a locked app without a .bundle directory
91
+ - require gems in the order that the resolver determines
92
+ - make the tests platform agnostic so we can confirm that they're green on JRuby
93
+ - fixes for Ruby 1.9
94
+
95
+ ## 0.9.5 (Feburary 12, 2010)
96
+
97
+ Features:
98
+
99
+ - added support for :path => "relative/path"
100
+ - added support for older versions of git
101
+ - added `bundle install --disable-shared-gems`
102
+ - Bundler.require fails silently if a library does not have a file on the load path with its name
103
+ - Basic support for multiple rubies by namespacing the default bundle path using the version and engine
104
+
105
+ Bugfixes:
106
+
107
+ - if the bundle is locked and .bundle/environment.rb is not present when Bundler.setup is called, generate it
108
+ - same if it's not present with `bundle check`
109
+ - same if it's not present with `bundle install`
@@ -79,7 +79,7 @@ Note that Bundler adds all the gems without an explicit group name to the
79
79
  Groups are involved in a number of scenarios:
80
80
 
81
81
  1. When installing gems using bundle install, you can choose to leave
82
- out any group by specifying `--without {group name}`. This can be
82
+ out any group by specifying `--without group1 group2`. This can be
83
83
  helpful if, for instance, you have a gem that you cannot compile
84
84
  in certain environments.
85
85
  2. When setting up load paths using Bundler.setup, Bundler will, by
@@ -208,8 +208,8 @@ API calls in your Gemfile, and some workarounds if you are using Rails 2.3.
208
208
  ### Rails 2.3
209
209
 
210
210
  Using Bundler 0.9 with Rails 2.3 requires adding a preinitializer, and
211
- making a few changes to boot.rb. The exact changes needed can be found at
212
- [http://gist.github.com/302406](http://gist.github.com/302406).
211
+ making a few changes to boot.rb. A detailed description of the changes
212
+ needed can be found in [Bundler 0.9 and Rails 2.3.5](http://andre.arko.net/2010/02/13/using-bundler-09-with-rails-235/).
213
213
 
214
214
  ### Gemfile Removals
215
215
 
@@ -274,7 +274,7 @@ Bundler 0.9 changes the following Bundler 0.8 Gemfile APIs:
274
274
 
275
275
  ## More information
276
276
 
277
- Explanations of common Bundler use cases can be found in [Using Bundler in Real Life](http://yehudakatz.com/2010/02/09/using-bundler-in-real-life/). The general philosophy behind Bundler 0.9 is explained at some length in [Bundler 0.9: Heading Toward 1.0](http://yehudakatz.com/2010/02/01/bundler-0-9-heading-toward-1-0/).
277
+ Explanations of common Bundler use cases can be found in [Using Bundler in Real Life](http://yehudakatz.com/2010/02/09/using-bundler-in-real-life/). The general philosophy behind Bundler 0.9 is explained at some length in [Bundler 0.9: Heading Toward 1.0](http://yehudakatz.com/2010/02/01/bundler-0-9-heading-toward-1-0/). Using Bundler with a Rails 2.3.5 app is explained with more detail in [Bundler 0.9 and Rails 2.3.5](http://andre.arko.net/2010/02/13/using-bundler-09-with-rails-235/).
278
278
 
279
279
  ### Deploying to memory-constrained servers
280
280
 
@@ -286,12 +286,19 @@ Any remaining questions may be asked via IRC in [#carlhuda](irc://irc.freenode.n
286
286
 
287
287
  ## Reporting bugs
288
288
 
289
- 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/).
289
+ Before reporting a bug, try these troubleshooting steps:
290
+
291
+ rm -rf ~/.bundle/ ~/.gem/ .bundle/ Gemfile.lock
292
+ bundle install
293
+
294
+ If you are still having problems, please report bugs to the github issue tracker for the project, located at [http://github.com/carlhuda/bundler/issues/](http://github.com/carlhuda/bundler/issues/).
290
295
 
291
296
  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:
292
297
 
293
298
  - Whether you have locked or not
294
299
  - What version of bundler you are using
300
+ - What version of Ruby you are using
301
+ - Whether you are using RVM, and if so what version
295
302
  - Your Gemfile
296
303
  - The command you ran to generate exception(s)
297
304
  - The exception backtrace(s)
@@ -0,0 +1,51 @@
1
+ We will be releasing one more point release (0.10.x) followed by 1.0. While
2
+ the following reflects our current thinking, critical bugs may alter it
3
+ somewhat.
4
+
5
+ # 0.10
6
+
7
+ - No breaking changes to the Gemfile are expected
8
+ - We expect to modify the format of Gemfile.lock.
9
+ - This should be the final change; it will not change for 1.0
10
+ - The Gemfile.lock generated by 0.9 will continue to work until 1.0
11
+ - If you use Bundler 0.10, we will transparently update the format
12
+ - This means: you will not be able to upgrade a locked app
13
+ directly from 0.9 to 1.0.
14
+ - Bundler 0.10 will automatically generate Gemfile.lock when any
15
+ resolve is successful.
16
+ - bundle install will conservatively update Gemfile.lock from the
17
+ last successful resolve if the Gemfile has been modified since
18
+ the last use of bundler.
19
+ - This means that adding a new gem to the Gemfile that does not
20
+ conflict with existing gems will not force an update of other
21
+ gems.
22
+ - This also means that we will not force an update to previously
23
+ resolved dependencies as long as they are compatible with some
24
+ valid version of the new dependency.
25
+ - When removing a gem, bundle install will simply remove it, without
26
+ recalculating all dependencies.
27
+ - We will be adding `bundle update` for the case where you -do-
28
+ wish to re-resolve all dependencies and update everything to the
29
+ latest version.
30
+ - bundle update will also take a gem name, if you want to force
31
+ an update to just a single gem (and its dependencies).
32
+ - Add a way to install dependencies that require build options
33
+ - Add a way to specify groups that are opt-in at install-time,
34
+ rather than opt-out.
35
+ - Some additional features that we have tagged for 0.10. For up
36
+ to date information, please visit
37
+ http://github.com/carlhuda/bundler/issues/labels/0.10
38
+
39
+ # 1.0
40
+
41
+ - No breaking changes to the Gemfile are expected
42
+ - No breaking changes to the Gemfile.lock are expected
43
+ - No major changes to the workflow are expected
44
+ - Reduce open bug count to 0
45
+ - Some additional features that require more thought. For details,
46
+ see http://github.com/carlhuda/bundler/issues/labels/1.0
47
+
48
+ # No Breaking changes
49
+
50
+ We expect no breaking changes of the Gemfile, Gemfile.lock, or
51
+ basic workflow for 1.x releases.
@@ -4,7 +4,7 @@ require 'yaml'
4
4
  require 'bundler/rubygems_ext'
5
5
 
6
6
  module Bundler
7
- VERSION = "0.9.11"
7
+ VERSION = "0.9.12"
8
8
 
9
9
  autoload :Definition, 'bundler/definition'
10
10
  autoload :Dependency, 'bundler/dependency'
@@ -17,6 +17,7 @@ module Bundler
17
17
  autoload :Runtime, 'bundler/runtime'
18
18
  autoload :Settings, 'bundler/settings'
19
19
  autoload :SharedHelpers, 'bundler/shared_helpers'
20
+ autoload :SpecSet, 'bundler/spec_set'
20
21
  autoload :Source, 'bundler/source'
21
22
  autoload :Specification, 'bundler/specification'
22
23
  autoload :UI, 'bundler/ui'
@@ -38,11 +38,12 @@ module Bundler
38
38
  Bundler.ui.error "Try running `bundle install`"
39
39
  exit 1
40
40
  else
41
- not_installed = env.specs.select { |spec| !spec.loaded_from }
41
+ not_installed = env.requested_specs.select { |spec| !spec.loaded_from }
42
42
 
43
43
  if not_installed.any?
44
44
  not_installed.each { |s| Bundler.ui.error "#{s.name} (#{s.version}) is cached, but not installed" }
45
45
  Bundler.ui.error "Try running `bundle install`"
46
+ exit 1
46
47
  else
47
48
  Bundler.ui.info "The Gemfile's dependencies are satisfied"
48
49
  end
@@ -68,11 +69,13 @@ module Bundler
68
69
  remove_lockfiles if options[:relock]
69
70
 
70
71
  Installer.install(Bundler.root, Bundler.definition, opts)
71
- # Ensures that .bundle/environment.rb exists
72
- # TODO: Figure out a less hackish way to do this
73
- Bundler.load
74
72
 
75
73
  lock if options[:relock]
74
+ rescue GemNotFound => e
75
+ if Bundler.definition.sources.empty?
76
+ Bundler.ui.warn "Your Gemfile doesn't have any sources. You can add one with a line like 'source :gemcutter'"
77
+ end
78
+ raise e
76
79
  end
77
80
 
78
81
  desc "lock", "Locks the bundle to the current set of dependencies, including all child dependencies."
@@ -32,20 +32,6 @@ module Bundler
32
32
  @sources = sources
33
33
  end
34
34
 
35
- def local_index
36
- @local_index ||= begin
37
- index = Index.new
38
-
39
- sources.each do |source|
40
- next unless source.respond_to?(:local_specs)
41
- index = source.local_specs.merge(index)
42
- end
43
-
44
- index = Index.from_installed_gems.merge(index)
45
- Index.from_cached_specs("#{Bundler.bundle_path}/cache").merge(index)
46
- end
47
- end
48
-
49
35
  def groups
50
36
  dependencies.map { |d| d.groups }.flatten.uniq
51
37
  end
@@ -9,22 +9,107 @@ module Bundler
9
9
  @definition = definition
10
10
  end
11
11
 
12
+ def index
13
+ @index ||= Index.build do |idx|
14
+ idx.use runtime_gems
15
+ idx.use Index.cached_gems
16
+ end
17
+ end
18
+
19
+ def requested_specs
20
+ @requested_specs ||= begin
21
+ groups = @definition.groups - Bundler.settings.without
22
+ groups.map! { |g| g.to_sym }
23
+ groups.any? ? specs_for(groups) : []
24
+ end
25
+ end
26
+
12
27
  private
13
28
 
14
- def group_specs(specs)
15
- dependencies.each do |d|
16
- spec = specs.find { |s| s.name == d.name }
17
- group_spec(specs, spec, d.groups)
29
+ def runtime_gems
30
+ @runtime_gems ||= Index.build do |i|
31
+ sources.each do |s|
32
+ i.use s.local_specs if s.respond_to?(:local_specs)
33
+ end
34
+
35
+ i.use Index.installed_gems
18
36
  end
19
- specs
20
37
  end
21
38
 
22
- def group_spec(specs, spec, groups)
23
- spec.groups.concat(groups)
24
- spec.groups.uniq!
25
- spec.dependencies.select { |d| d.type != :development }.each do |d|
26
- spec = specs.find { |s| s.name == d.name }
27
- group_spec(specs, spec, groups)
39
+ def specs_for(groups)
40
+ deps = dependencies.select { |d| (d.groups & groups).any? }
41
+ # deps.any? ? specs.for(deps) : specs
42
+ specs.for(deps)
43
+ end
44
+
45
+ # ==== Locking
46
+
47
+ def locked?
48
+ File.exist?("#{root}/Gemfile.lock")
49
+ end
50
+
51
+ def write_rb_lock
52
+ shared_helpers = File.read(File.expand_path("../shared_helpers.rb", __FILE__))
53
+ template = File.read(File.expand_path("../templates/environment.erb", __FILE__))
54
+ erb = ERB.new(template, nil, '-')
55
+ FileUtils.mkdir_p(rb_lock_file.dirname)
56
+ File.open(rb_lock_file, 'w') do |f|
57
+ f.puts erb.result(binding)
58
+ end
59
+ end
60
+
61
+ def rb_lock_file
62
+ root.join(".bundle/environment.rb")
63
+ end
64
+
65
+ def gemfile_fingerprint
66
+ Digest::SHA1.hexdigest(File.read("#{root}/Gemfile"))
67
+ end
68
+
69
+ def specs_for_lock_file
70
+ requested_specs.map do |s|
71
+ hash = {
72
+ :name => s.name,
73
+ :load_paths => s.load_paths
74
+ }
75
+ if s.respond_to?(:virtual) && s.virtual
76
+ hash[:virtual_spec] = s.to_ruby
77
+ else
78
+ hash[:loaded_from] = s.loaded_from.to_s
79
+ end
80
+ hash
81
+ end
82
+ end
83
+
84
+ def autorequires_for_groups(*groups)
85
+ groups.map! { |g| g.to_sym }
86
+ autorequires = Hash.new { |h,k| h[k] = [] }
87
+
88
+ ordered_deps = []
89
+ specs = groups.any? ? specs_for(groups) : requested_specs
90
+ specs.each do |g|
91
+ dep = @definition.dependencies.find{|d| d.name == g.name }
92
+ ordered_deps << dep if dep && !ordered_deps.include?(dep)
93
+ end
94
+
95
+ ordered_deps.each do |dep|
96
+ dep.groups.each do |group|
97
+ # If there is no autorequire, then rescue from
98
+ # autorequiring the gems name
99
+ if dep.autorequire
100
+ dep.autorequire.each do |file|
101
+ autorequires[group] << [file, true]
102
+ end
103
+ else
104
+ autorequires[group] << [dep.name, false]
105
+ end
106
+ end
107
+ end
108
+
109
+ if groups.empty?
110
+ autorequires
111
+ else
112
+ groups.inject({}) { |h,g| h[g] = autorequires[g]; h }
28
113
  end
29
114
  end
30
115
  end
@@ -1,9 +1,33 @@
1
1
  module Bundler
2
2
  class Index
3
- def self.from_installed_gems
3
+ def self.build
4
+ i = new
5
+ yield i
6
+ i
7
+ end
8
+
9
+ def self.installed_gems
4
10
  Source::SystemGems.new.specs
5
11
  end
6
12
 
13
+ def self.cached_gems
14
+ build do |idx|
15
+ idx.use application_cached_gems
16
+ idx.use system_cached_gems
17
+ end
18
+ end
19
+
20
+ def self.application_cached_gems
21
+ path = "#{Bundler.root}/vendor/cache"
22
+ if File.directory?(path)
23
+ from_cached_specs(path)
24
+ end
25
+ end
26
+
27
+ def self.system_cached_gems
28
+ from_cached_specs("#{Bundler.bundle_path}/cache")
29
+ end
30
+
7
31
  def self.from_cached_specs(path)
8
32
  Source::GemCache.new("path" => path).specs
9
33
  end
@@ -52,28 +76,19 @@ module Bundler
52
76
  end
53
77
  end
54
78
 
55
- def merge!(other)
56
- other.each do |spec|
57
- self << spec
79
+ def use(other)
80
+ return unless other
81
+ other.each do |s|
82
+ next if search_by_spec(s).any?
83
+ @specs[s.name] << s
58
84
  end
59
85
  self
60
86
  end
61
87
 
62
- def merge(other)
63
- dup.merge!(other)
64
- end
65
-
66
- def freeze
67
- @specs.each do |k,v|
68
- v.freeze
69
- end
70
- super
71
- end
72
-
73
88
  private
74
89
 
75
90
  def search_by_spec(spec)
76
- @specs[spec.name].select { |s| s.version == spec.version }
91
+ @specs[spec.name].select { |s| s.version == spec.version && s.platform == spec.platform }
77
92
  end
78
93
 
79
94
  def search_by_dependency(dependency)
@@ -21,20 +21,22 @@ module Bundler
21
21
  specs.each do |spec|
22
22
  spec.source.fetch(spec) if spec.source.respond_to?(:fetch)
23
23
 
24
- if spec.groups & Bundler.settings.without == spec.groups
24
+ unless requested_specs.include?(spec)
25
25
  Bundler.ui.debug " * Not in requested group; skipping."
26
26
  next
27
27
  end
28
28
 
29
- # unless spec.source.is_a?(Source::SystemGems)
30
- Bundler.ui.info "Installing #{spec.name} (#{spec.version}) from #{spec.source} "
31
- # end
29
+ Bundler.ui.info "Installing #{spec.name} (#{spec.version}) from #{spec.source} "
32
30
 
33
31
  spec.source.install(spec)
34
32
 
35
33
  Bundler.ui.info ""
36
34
  end
37
35
 
36
+ if locked?
37
+ write_rb_lock
38
+ end
39
+
38
40
  Bundler.ui.confirm "Your bundle is complete!"
39
41
  end
40
42
 
@@ -47,7 +49,7 @@ module Bundler
47
49
  end
48
50
 
49
51
  def specs
50
- @specs ||= group_specs(resolve_locally || resolve_remotely)
52
+ @specs ||= resolve_locally || resolve_remotely
51
53
  end
52
54
 
53
55
  private
@@ -67,7 +69,7 @@ module Bundler
67
69
  end
68
70
 
69
71
  # Run a resolve against the locally available gems
70
- specs = Resolver.resolve(actual_dependencies, local_index, source_requirements)
72
+ specs = Resolver.resolve(actual_dependencies, index, source_requirements)
71
73
 
72
74
  # Simple logic for now. Can improve later.
73
75
  specs.length == actual_dependencies.length && specs
@@ -76,7 +78,7 @@ module Bundler
76
78
  end
77
79
 
78
80
  def resolve_remotely
79
- index # trigger building the index
81
+ remote_index # trigger building the index
80
82
  Bundler.ui.info "Resolving dependencies"
81
83
  source_requirements = {}
82
84
  actual_dependencies.each do |dep|
@@ -84,7 +86,7 @@ module Bundler
84
86
  source_requirements[dep.name] = dep.source.specs
85
87
  end
86
88
 
87
- specs = Resolver.resolve(actual_dependencies, index, source_requirements)
89
+ specs = Resolver.resolve(actual_dependencies, remote_index, source_requirements)
88
90
  specs
89
91
  end
90
92
 
@@ -92,58 +94,23 @@ module Bundler
92
94
  dep.requirement.requirements.any? { |op,_| op != '=' }
93
95
  end
94
96
 
95
- def index
96
- @index ||= begin
97
- index = Index.new
98
-
99
- rg_sources = sources.select { |s| s.is_a?(Source::Rubygems) }
100
- other_sources = sources.select { |s| !s.is_a?(Source::Rubygems) }
97
+ def remote_index
98
+ @remote_index ||= Index.build do |idx|
99
+ rubygems, other = sources.partition { |s| Source::Rubygems === s }
101
100
 
102
- other_sources.each do |source|
103
- i = source.specs
101
+ other.each do |source|
104
102
  Bundler.ui.debug "Source: Processing index"
105
- index = i.merge(index)
103
+ idx.use source.specs
106
104
  end
107
105
 
108
- index = Index.from_installed_gems.merge(index)
109
- index = Index.from_cached_specs("#{Bundler.bundle_path}/cache").merge(index)
106
+ idx.use Index.installed_gems
107
+ idx.use Index.cached_gems
110
108
 
111
- if File.directory?("#{root}/vendor/cache")
112
- index = cache_source.specs.merge(index)
113
- end
114
-
115
- rg_sources.each do |source|
116
- i = source.specs
109
+ rubygems.each do |source|
117
110
  Bundler.ui.debug "Source: Processing index"
118
- index = i.merge(index)
119
- end
120
-
121
- index
122
- end
123
- end
124
-
125
- def local_index
126
- @local_index ||= begin
127
- index = Index.new
128
-
129
- sources.each do |source|
130
- next unless source.respond_to?(:local_specs)
131
- index = source.local_specs.merge(index)
132
- end
133
-
134
- index = Index.from_installed_gems.merge(index)
135
-
136
- if File.directory?("#{root}/vendor/cache")
137
- index = cache_source.specs.merge(index).freeze
111
+ idx.use source.specs
138
112
  end
139
-
140
- Index.from_cached_specs("#{Bundler.bundle_path}/cache").merge(index)
141
113
  end
142
114
  end
143
-
144
- def cache_source
145
- Source::GemCache.new("path" => "#{root}/vendor/cache")
146
- end
147
-
148
115
  end
149
116
  end
@@ -52,15 +52,7 @@ module Bundler
52
52
  raise VersionConflict, "No compatible versions could be found for required dependencies:\n #{output}"
53
53
  nil
54
54
  end
55
- if result
56
- # Dependency ordering was busted anyway. This will be revisted in 0.10
57
- ordered = []
58
- ordered << result['rake']
59
- ordered.concat result.values
60
- ordered.compact!
61
- ordered.uniq!
62
- ordered
63
- end
55
+ SpecSet.new(result.values)
64
56
  end
65
57
 
66
58
  def initialize(index, source_requirements)
@@ -15,12 +15,16 @@ module Bundler
15
15
  # Has to happen first
16
16
  clean_load_path
17
17
 
18
- specs = specs_for(*groups)
18
+ specs = groups.any? ? specs_for(groups) : requested_specs
19
19
 
20
20
  cripple_rubygems(specs)
21
21
 
22
22
  # Activate the specs
23
23
  specs.each do |spec|
24
+ unless spec.loaded_from
25
+ raise GemNotFound, "#{spec.full_name} is not installed. Try running `bundle install`."
26
+ end
27
+
24
28
  Gem.loaded_specs[spec.name] = spec
25
29
  $LOAD_PATH.unshift(*spec.load_paths)
26
30
  end
@@ -63,10 +67,6 @@ module Bundler
63
67
  Bundler.ui.info("The bundle is now locked. Use `bundle show` to list the gems in the environment.")
64
68
  end
65
69
 
66
- def locked?
67
- File.exist?("#{root}/Gemfile.lock") || File.exist?("#{root}/.bundle/environment.rb")
68
- end
69
-
70
70
  def dependencies_for(*groups)
71
71
  if groups.empty?
72
72
  dependencies
@@ -75,13 +75,6 @@ module Bundler
75
75
  end
76
76
  end
77
77
 
78
- def specs_for(*groups)
79
- groups = @definition.groups if groups.empty?
80
- groups -= Bundler.settings.without
81
- groups.map! { |g| g.to_sym }
82
- specs.select { |s| (s.groups & groups).any? }
83
- end
84
-
85
78
  def specs
86
79
  @specs ||= begin
87
80
  source_requirements = {}
@@ -90,16 +83,12 @@ module Bundler
90
83
  source_requirements[dep.name] = dep.source.local_specs
91
84
  end
92
85
 
93
- group_specs(Resolver.resolve(@definition.actual_dependencies, index, source_requirements))
86
+ Resolver.resolve(@definition.actual_dependencies, index, source_requirements)
94
87
  end
95
88
  end
96
89
 
97
90
  alias gems specs
98
91
 
99
- def index
100
- @definition.local_index
101
- end
102
-
103
92
  def cache
104
93
  cache_path = "#{root}/vendor/cache/"
105
94
  FileUtils.mkdir_p(cache_path)
@@ -126,20 +115,6 @@ module Bundler
126
115
  specs.map { |s| s.load_paths }.flatten
127
116
  end
128
117
 
129
- def rb_lock_file
130
- root.join(".bundle/environment.rb")
131
- end
132
-
133
- def write_rb_lock
134
- shared_helpers = File.read(File.expand_path("../shared_helpers.rb", __FILE__))
135
- template = File.read(File.expand_path("../templates/environment.erb", __FILE__))
136
- erb = ERB.new(template, nil, '-')
137
- FileUtils.mkdir_p(rb_lock_file.dirname)
138
- File.open(rb_lock_file, 'w') do |f|
139
- f.puts erb.result(binding)
140
- end
141
- end
142
-
143
118
  def write_yml_lock
144
119
  yml = details.to_yaml
145
120
  File.open("#{root}/Gemfile.lock", 'w') do |f|
@@ -165,49 +140,5 @@ module Bundler
165
140
  end
166
141
  details
167
142
  end
168
-
169
- def gemfile_fingerprint
170
- Digest::SHA1.hexdigest(File.read("#{root}/Gemfile"))
171
- end
172
-
173
- def specs_for_lock_file
174
- specs_for.map do |s|
175
- hash = {}
176
- hash[:loaded_from] = s.loaded_from.to_s
177
- hash[:load_paths] = s.load_paths
178
- hash
179
- end
180
- end
181
-
182
- def autorequires_for_groups(*groups)
183
- groups.map! { |g| g.to_sym }
184
- autorequires = Hash.new { |h,k| h[k] = [] }
185
-
186
- ordered_deps = []
187
- specs_for(*groups).each do |g|
188
- dep = @definition.dependencies.find{|d| d.name == g.name }
189
- ordered_deps << dep if dep && !ordered_deps.include?(dep)
190
- end
191
-
192
- ordered_deps.each do |dep|
193
- dep.groups.each do |group|
194
- # If there is no autorequire, then rescue from
195
- # autorequiring the gems name
196
- if dep.autorequire
197
- dep.autorequire.each do |file|
198
- autorequires[group] << [file, true]
199
- end
200
- else
201
- autorequires[group] << [dep.name, false]
202
- end
203
- end
204
- end
205
-
206
- if groups.empty?
207
- autorequires
208
- else
209
- groups.inject({}) { |h,g| h[g] = autorequires[g]; h }
210
- end
211
- end
212
143
  end
213
144
  end
@@ -40,6 +40,8 @@ module Bundler
40
40
  :bin_dir => "#{Gem.dir}/bin"
41
41
 
42
42
  installer.install
43
+
44
+ spec.loaded_from = "#{Gem.dir}/specifications/#{spec.full_name}.gemspec"
43
45
  end
44
46
 
45
47
  private
@@ -62,7 +64,7 @@ module Bundler
62
64
  end
63
65
  end
64
66
 
65
- index.freeze
67
+ index
66
68
  ensure
67
69
  Gem.sources = old
68
70
  end
@@ -131,6 +133,7 @@ module Bundler
131
133
  :bin_dir => "#{Gem.dir}/bin"
132
134
 
133
135
  installer.install
136
+ spec.loaded_from = "#{Gem.dir}/specifications/#{spec.full_name}.gemspec"
134
137
  end
135
138
  end
136
139
 
@@ -152,6 +155,7 @@ module Bundler
152
155
  s.version = Gem::Version.new(options["version"])
153
156
  s.summary = "Fake gemspec for #{options["name"]}"
154
157
  s.relative_loaded_from = "#{options["name"]}.gemspec"
158
+ s.virtual = true
155
159
  end
156
160
  end
157
161
  end
@@ -180,7 +184,7 @@ module Bundler
180
184
  raise PathError, "The path `#{path}` does not exist."
181
185
  end
182
186
 
183
- index.freeze
187
+ index
184
188
  end
185
189
 
186
190
  def local_specs
@@ -252,7 +256,7 @@ module Bundler
252
256
  # Start by making sure the git cache is up to date
253
257
  cache
254
258
  checkout
255
- @specs ||= load_spec_files
259
+ local_specs
256
260
  end
257
261
 
258
262
  def install(spec)
@@ -312,17 +316,17 @@ module Bundler
312
316
  def cache
313
317
  if cache_path.exist?
314
318
  Bundler.ui.info "Updating #{uri}"
315
- in_cache { git "fetch --quiet #{uri} master:master" }
319
+ in_cache { git "fetch --quiet '#{uri}' master:master" }
316
320
  else
317
321
  Bundler.ui.info "Fetching #{uri}"
318
322
  FileUtils.mkdir_p(cache_path.dirname)
319
- git "clone #{uri} #{cache_path} --bare --no-hardlinks"
323
+ git "clone '#{uri}' '#{cache_path}' --bare --no-hardlinks"
320
324
  end
321
325
  end
322
326
 
323
327
  def checkout
324
- unless File.exist?("#{path}/.git")
325
- %x(git clone --no-checkout file://#{cache_path} #{path})
328
+ unless File.exist?(path.join(".git"))
329
+ git "clone --no-checkout '#{cache_path}' '#{path}'"
326
330
  end
327
331
  Dir.chdir(path) do
328
332
  git "fetch --quiet"
@@ -0,0 +1,65 @@
1
+ require 'tsort'
2
+
3
+ module Bundler
4
+ class SpecSet
5
+ include TSort, Enumerable
6
+
7
+ def initialize(specs)
8
+ @specs = specs.sort_by { |s| s.name }
9
+ end
10
+
11
+ def each
12
+ sorted.each { |s| yield s }
13
+ end
14
+
15
+ def length
16
+ @specs.length
17
+ end
18
+
19
+ def for(*deps)
20
+ specs = {}
21
+ deps.flatten.each do |dep|
22
+ current = lookup[dep.respond_to?(:name) ? dep.name : dep]
23
+ append_subgraph(specs, current)
24
+ end
25
+
26
+ sorted.select { |s| specs[s.name] }
27
+ end
28
+
29
+ def to_a
30
+ sorted.dup
31
+ end
32
+
33
+ private
34
+
35
+ def append_subgraph(specs, current)
36
+ return if specs[current.name]
37
+ specs[current.name] = true
38
+ current.dependencies.each do |dep|
39
+ next unless dep.type == :runtime
40
+ append_subgraph(specs, lookup[dep.name])
41
+ end
42
+ end
43
+
44
+ def sorted
45
+ @sorted ||= ([lookup['rake']] + tsort).compact.uniq
46
+ end
47
+
48
+ def lookup
49
+ @lookup ||= Hash.new do |h,k|
50
+ h[k] = @specs.find { |s| s.name == k }
51
+ end
52
+ end
53
+
54
+ def tsort_each_node
55
+ @specs.each { |s| yield s }
56
+ end
57
+
58
+ def tsort_each_child(s)
59
+ s.dependencies.sort_by { |d| d.name }.each do |d|
60
+ next if d.type == :development
61
+ yield lookup[d.name]
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,6 +1,6 @@
1
1
  module Bundler
2
2
  class Specification < Gem::Specification
3
- attr_accessor :relative_loaded_from
3
+ attr_accessor :relative_loaded_from, :virtual
4
4
 
5
5
  def self.from_gemspec(gemspec)
6
6
  spec = allocate
@@ -12,7 +12,7 @@ module Bundler
12
12
 
13
13
  def loaded_from
14
14
  return super unless relative_loaded_from
15
- source.path.join(relative_loaded_from)
15
+ source.path.join(relative_loaded_from).to_s
16
16
  end
17
17
 
18
18
  def full_gem_path
@@ -14,7 +14,12 @@ module Bundler
14
14
  <%= spec.inspect %>,
15
15
  <% end -%>
16
16
  ].map do |hash|
17
- spec = eval(File.read(hash[:loaded_from]), binding, hash[:loaded_from])
17
+ if hash[:loaded_from]
18
+ dir = File.dirname(hash[:loaded_from])
19
+ spec = Dir.chdir(dir){ eval(File.read(hash[:loaded_from]), binding, hash[:loaded_from]) }
20
+ else
21
+ spec = eval(hash[:virtual_spec], binding, "<virtual spec for '#{hash[:name]}'>")
22
+ end
18
23
  spec.loaded_from = hash[:loaded_from]
19
24
  spec.require_paths = hash[:load_paths]
20
25
  spec
metadata CHANGED
@@ -5,17 +5,18 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 9
8
- - 11
9
- version: 0.9.11
8
+ - 12
9
+ version: 0.9.12
10
10
  platform: ruby
11
11
  authors:
12
12
  - Carl Lerche
13
13
  - Yehuda Katz
14
+ - "Andr\xC3\xA9 Arko"
14
15
  autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2010-03-09 00:00:00 -08:00
19
+ date: 2010-03-17 00:00:00 -07:00
19
20
  default_executable:
20
21
  dependencies: []
21
22
 
@@ -45,6 +46,7 @@ files:
45
46
  - lib/bundler/setup.rb
46
47
  - lib/bundler/shared_helpers.rb
47
48
  - lib/bundler/source.rb
49
+ - lib/bundler/spec_set.rb
48
50
  - lib/bundler/specification.rb
49
51
  - lib/bundler/templates/environment.erb
50
52
  - lib/bundler/templates/Gemfile
@@ -69,15 +71,14 @@ files:
69
71
  - lib/bundler/vendor/thor.rb
70
72
  - lib/bundler.rb
71
73
  - LICENSE
72
- - README.markdown
73
- - ROADMAP.textile
74
+ - README.md
75
+ - ROADMAP.md
76
+ - CHANGELOG.md
74
77
  has_rdoc: true
75
78
  homepage: http://github.com/carlhuda/bundler
76
79
  licenses: []
77
80
 
78
- post_install_message: |-
79
- Due to a rubygems bug, you must uninstall older versions of the bundler gem for 0.9 to work.
80
- If you still need bundler 0.8, install the 'bundler08' gem.
81
+ post_install_message:
81
82
  rdoc_options: []
82
83
 
83
84
  require_paths:
@@ -1,51 +0,0 @@
1
- We will be releasing one more point release (0.10.x) followed by 1.0. While
2
- the following reflects our current thinking, critical bugs may alter it
3
- somewhat.
4
-
5
- h1. 0.10
6
-
7
- * No breaking changes to the Gemfile are expected
8
- * We expect to modify the format of Gemfile.lock.
9
- ** This should be the final change; it will not change for 1.0
10
- ** The Gemfile.lock generated by 0.9 will continue to work until 1.0
11
- ** If you use Bundler 0.10, we will transparently update the format
12
- ** This means: you will not be able to upgrade a locked app
13
- directly from 0.9 to 1.0.
14
- * Bundler 0.10 will automatically generate Gemfile.lock when any
15
- resolve is successful.
16
- * bundle install will conservatively update Gemfile.lock from the
17
- last successful resolve if the Gemfile has been modified since
18
- the last use of bundler.
19
- ** This means that adding a new gem to the Gemfile that does not
20
- conflict with existing gems will not force an update of other
21
- gems.
22
- ** This also means that we will not force an update to previously
23
- resolved dependencies as long as they are compatible with some
24
- valid version of the new dependency.
25
- ** When removing a gem, bundle install will simply remove it, without
26
- recalculating all dependencies.
27
- * We will be adding `bundle update` for the case where you *do*
28
- wish to re-resolve all dependencies and update everything to the
29
- latest version.
30
- ** bundle update will also take a gem name, if you want to force
31
- an update to just a single gem (and its dependencies).
32
- * Add a way to install dependencies that require build options
33
- * Add a way to specify groups that are opt-in at install-time,
34
- rather than opt-out.
35
- * Some additional features that we have tagged for 0.10. For up
36
- to date information, please visit
37
- http://github.com/carlhuda/bundler/issues/labels/0.10
38
-
39
- h1. 1.0
40
-
41
- * No breaking changes to the Gemfile are expected
42
- * No breaking changes to the Gemfile.lock are expected
43
- * No major changes to the workflow are expected
44
- * Reduce open bug count to 0
45
- * Some additional features that require more thought. For details,
46
- see http://github.com/carlhuda/bundler/issues/labels/1.0
47
-
48
- h1. No Breaking changes
49
-
50
- We expect no breaking changes of the Gemfile, Gemfile.lock, or
51
- basic workflow for 1.x releases.