You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
4.8 KiB
123 lines
4.8 KiB
diff --git a/bin/vagrant b/bin/vagrant
|
|
index fce68c8..781fc63 100755
|
|
--- a/bin/vagrant
|
|
+++ b/bin/vagrant
|
|
@@ -69,6 +69,11 @@ end
|
|
require "bundler"
|
|
begin
|
|
$vagrant_bundler_runtime = Bundler.setup(:default, :plugins)
|
|
+# Invalidate the cached Gemfile.lock if necessary and try again
|
|
+rescue Bundler::GemNotFound
|
|
+ FileUtils.rm File.expand_path("~/.vagrant.d/Gemfile") if File.exists? File.expand_path("~/.vagrant.d/Gemfile")
|
|
+ FileUtils.rm File.expand_path("~/.vagrant.d/Gemfile.lock") if File.exists? File.expand_path("~/.vagrant.d/Gemfile.lock")
|
|
+ $vagrant_bundler_runtime = Bundler.setup(:default, :plugins)
|
|
rescue Bundler::GemNotFound
|
|
$stderr.puts "Bundler, the underlying system used to manage Vagrant plugins,"
|
|
$stderr.puts "is reporting that a plugin or its dependency can't be found."
|
|
diff --git a/lib/vagrant/bundler.rb b/lib/vagrant/bundler.rb
|
|
index ea8c056..0543963 100644
|
|
--- a/lib/vagrant/bundler.rb
|
|
+++ b/lib/vagrant/bundler.rb
|
|
@@ -63,6 +63,13 @@ module Vagrant
|
|
@configfile = File.open(Tempfile.new("vagrant").path + "1", "w+")
|
|
@configfile.close
|
|
|
|
+ # Ensure the path to user's Gemfile exists
|
|
+ gemfile = Vagrant.user_data_path.join("Gemfile")
|
|
+ unless File.exists? gemfile
|
|
+ FileUtils.mkdir_p(File.dirname(gemfile))
|
|
+ File.open(gemfile, 'w') {}
|
|
+ end
|
|
+
|
|
# Build up the Gemfile for our Bundler context. We make sure to
|
|
# lock Vagrant to our current Vagrant version. In addition to that,
|
|
# we add all our plugin dependencies.
|
|
@@ -141,7 +148,7 @@ module Vagrant
|
|
|
|
# Clean removes any unused gems.
|
|
def clean(plugins)
|
|
- gemfile = build_gemfile(plugins)
|
|
+ gemfile = build_gemfile(plugins, false, true)
|
|
lockfile = "#{gemfile.path}.lock"
|
|
definition = ::Bundler::Definition.build(gemfile, lockfile, nil)
|
|
root = File.dirname(gemfile.path)
|
|
@@ -172,11 +179,24 @@ module Vagrant
|
|
# Builds a valid Gemfile for use with Bundler given the list of
|
|
# plugins.
|
|
#
|
|
+ # @param [Hash|Bool] update Hash of gems to update or true for all
|
|
+ # @param [Bool] invalidate Invalidate Gemfile.lock
|
|
# @return [Tempfile]
|
|
- def build_gemfile(plugins)
|
|
+ def build_gemfile(plugins, update = false, invalidate = false)
|
|
sources = plugins.values.map { |p| p["sources"] }.flatten.compact.uniq
|
|
|
|
- f = File.open(Tempfile.new("vagrant").path + "2", "w+")
|
|
+ # Determine what gems to update
|
|
+ if update.is_a? Hash
|
|
+ update_gems = update[:gems]
|
|
+ elsif update === true
|
|
+ update_gems = plugins.map{ |p| p[0] }
|
|
+ else
|
|
+ update_gems = []
|
|
+ end
|
|
+
|
|
+ gemfile = Vagrant.user_data_path.join("Gemfile")
|
|
+ f = File.open(gemfile, "w+")
|
|
+
|
|
f.tap do |gemfile|
|
|
if !sources.include?("http://rubygems.org")
|
|
gemfile.puts(%Q[source "https://rubygems.org"])
|
|
@@ -190,6 +210,19 @@ module Vagrant
|
|
|
|
gemfile.puts(%Q[gemspec :path => "#{File.expand_path '../../..', __FILE__}"])
|
|
|
|
+ locked_gems = []
|
|
+
|
|
+ # Use Gemfile.lock to lock the gem versions
|
|
+ if ENV["VAGRANT_INTERNAL_BUNDLERIZED"] && File.exist?("#{gemfile.path}.lock") && !invalidate
|
|
+ lockfile = ::Bundler::LockfileParser.new(::Bundler.read_file("#{gemfile.path}.lock"))
|
|
+ lockfile.specs.each do |s|
|
|
+ if s.name != 'vagrant' && !(update_gems.include? s.name)
|
|
+ gemfile.puts(%Q[gem "#{s.name}", "#{s.version.to_s}"])
|
|
+ end
|
|
+ end
|
|
+ locked_gems = lockfile.specs.map(&:name) - update_gems
|
|
+ end
|
|
+
|
|
gemfile.puts("group :plugins do")
|
|
plugins.each do |name, plugin|
|
|
version = plugin["gem_version"]
|
|
@@ -199,13 +232,19 @@ module Vagrant
|
|
if plugin["require"] && plugin["require"] != ""
|
|
opts[:require] = plugin["require"]
|
|
end
|
|
-
|
|
- gemfile.puts(%Q[gem "#{name}", #{version.inspect}, #{opts.inspect}])
|
|
+ gemfile.puts(%Q[gem "#{name}", #{version.inspect}, #{opts.inspect}]) unless locked_gems.include? name
|
|
end
|
|
gemfile.puts("end")
|
|
-
|
|
gemfile.close
|
|
end
|
|
+
|
|
+ # Create Gemfile.lock if missing and re-generate Gemfile
|
|
+ if !File.exist?("#{f.path}.lock") && File.exist?(f.path)
|
|
+ lockfile = "#{f.path}.lock"
|
|
+ ENV['BUNDLE_GEMFILE'] = f.path
|
|
+ definition = ::Bundler::Definition.build(f.path, lockfile, false)
|
|
+ end
|
|
+ f
|
|
end
|
|
|
|
# This installs a set of plugins and optionally updates those gems.
|
|
@@ -215,7 +254,7 @@ module Vagrant
|
|
# can be a hash of options. See Bundler.definition.
|
|
# @return [Array<Gem::Specification>]
|
|
def internal_install(plugins, update, **extra)
|
|
- gemfile = build_gemfile(plugins)
|
|
+ gemfile = build_gemfile(plugins, update)
|
|
lockfile = "#{gemfile.path}.lock"
|
|
definition = ::Bundler::Definition.build(gemfile, lockfile, update)
|
|
root = File.dirname(gemfile.path)
|