commands/plugin: support installing from file
This commit is contained in:
parent
3f9fb2ef03
commit
86cab61c27
|
@ -1,3 +1,4 @@
|
||||||
|
require "monitor"
|
||||||
require "pathname"
|
require "pathname"
|
||||||
require "set"
|
require "set"
|
||||||
require "tempfile"
|
require "tempfile"
|
||||||
|
@ -17,6 +18,8 @@ module Vagrant
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
|
@monitor = Monitor.new
|
||||||
|
|
||||||
@gem_home = ENV["GEM_HOME"]
|
@gem_home = ENV["GEM_HOME"]
|
||||||
@gem_path = ENV["GEM_PATH"]
|
@gem_path = ENV["GEM_PATH"]
|
||||||
|
|
||||||
|
@ -59,6 +62,41 @@ module Vagrant
|
||||||
internal_install(plugins, nil)
|
internal_install(plugins, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Installs a local '*.gem' file so that Bundler can find it.
|
||||||
|
#
|
||||||
|
# @param [String] path Path to a local gem file.
|
||||||
|
# @return [Gem::Specification]
|
||||||
|
def install_local(path)
|
||||||
|
# We have to do this load here because this file can be loaded
|
||||||
|
# before RubyGems is actually loaded.
|
||||||
|
require "rubygems/dependency_installer"
|
||||||
|
begin
|
||||||
|
require "rubygems/format"
|
||||||
|
rescue LoadError
|
||||||
|
# rubygems 2.x
|
||||||
|
end
|
||||||
|
|
||||||
|
# If we're installing from a gem file, determine the name
|
||||||
|
# based on the spec in the file.
|
||||||
|
pkg = if defined?(Gem::Format)
|
||||||
|
# RubyGems 1.x
|
||||||
|
Gem::Format.from_file_by_path(path)
|
||||||
|
else
|
||||||
|
# RubyGems 2.x
|
||||||
|
Gem::Package.new(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Install the gem manually. If the gem exists locally, then
|
||||||
|
# Bundler shouldn't attempt to get it remotely.
|
||||||
|
with_isolated_gem do
|
||||||
|
installer = Gem::DependencyInstaller.new(
|
||||||
|
:document => [], :prerelease => false)
|
||||||
|
installer.install(path, "= #{pkg.spec.version}")
|
||||||
|
end
|
||||||
|
|
||||||
|
pkg.spec
|
||||||
|
end
|
||||||
|
|
||||||
# Update updates the given plugins, or every plugin if none is given.
|
# Update updates the given plugins, or every plugin if none is given.
|
||||||
#
|
#
|
||||||
# @param [Hash] plugins
|
# @param [Hash] plugins
|
||||||
|
@ -84,6 +122,21 @@ module Vagrant
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# During the duration of the yielded block, Bundler loud output
|
||||||
|
# is enabled.
|
||||||
|
def verbose
|
||||||
|
@monitor.synchronize do
|
||||||
|
begin
|
||||||
|
old_ui = ::Bundler.ui
|
||||||
|
require 'bundler/vendored_thor'
|
||||||
|
::Bundler.ui = ::Bundler::UI::Shell.new
|
||||||
|
yield
|
||||||
|
ensure
|
||||||
|
::Bundler.ui = old_ui
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
# Builds a valid Gemfile for use with Bundler given the list of
|
# Builds a valid Gemfile for use with Bundler given the list of
|
||||||
|
|
|
@ -29,6 +29,13 @@ module Vagrant
|
||||||
# @param [String] name Name of the plugin (gem)
|
# @param [String] name Name of the plugin (gem)
|
||||||
# @return [Gem::Specification]
|
# @return [Gem::Specification]
|
||||||
def install_plugin(name, **opts)
|
def install_plugin(name, **opts)
|
||||||
|
if name =~ /\.gem$/
|
||||||
|
# If this is a gem file, then we install that gem locally.
|
||||||
|
local_spec = Vagrant::Bundler.instance.install_local(name)
|
||||||
|
name = local_spec.name
|
||||||
|
opts[:version] = "= #{local_spec.version}"
|
||||||
|
end
|
||||||
|
|
||||||
plugins = installed_plugins
|
plugins = installed_plugins
|
||||||
plugins[name] = {
|
plugins[name] = {
|
||||||
"require" => opts[:require],
|
"require" => opts[:require],
|
||||||
|
@ -37,10 +44,18 @@ module Vagrant
|
||||||
}
|
}
|
||||||
|
|
||||||
result = nil
|
result = nil
|
||||||
Vagrant::Bundler.instance.install(plugins).each do |spec|
|
install_lambda = lambda do
|
||||||
next if spec.name != name
|
Vagrant::Bundler.instance.install(plugins).each do |spec|
|
||||||
next if result && result.version >= spec.version
|
next if spec.name != name
|
||||||
result = spec
|
next if result && result.version >= spec.version
|
||||||
|
result = spec
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if opts[:verbose]
|
||||||
|
Vagrant::Bundler.instance.verbose(&install_lambda)
|
||||||
|
else
|
||||||
|
install_lambda.call
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add the plugin to the state file
|
# Add the plugin to the state file
|
||||||
|
|
|
@ -1,12 +1,3 @@
|
||||||
require "rubygems"
|
|
||||||
require "rubygems/dependency_installer"
|
|
||||||
|
|
||||||
begin
|
|
||||||
require "rubygems/format"
|
|
||||||
rescue LoadError
|
|
||||||
# rubygems 2.x
|
|
||||||
end
|
|
||||||
|
|
||||||
require "log4r"
|
require "log4r"
|
||||||
require "vagrant/plugin/manager"
|
require "vagrant/plugin/manager"
|
||||||
|
|
||||||
|
@ -27,24 +18,6 @@ module VagrantPlugins
|
||||||
sources = env[:plugin_sources]
|
sources = env[:plugin_sources]
|
||||||
version = env[:plugin_version]
|
version = env[:plugin_version]
|
||||||
|
|
||||||
# Determine the plugin name we'll look for in the installed set
|
|
||||||
# in order to determine the version and all that.
|
|
||||||
find_plugin_name = plugin_name
|
|
||||||
if plugin_name =~ /\.gem$/
|
|
||||||
# If we're installing from a gem file, determine the name
|
|
||||||
# based on the spec in the file.
|
|
||||||
pkg = if defined?(Gem::Format)
|
|
||||||
# RubyGems 1.x
|
|
||||||
Gem::Format.from_file_by_path(plugin_name)
|
|
||||||
else
|
|
||||||
# RubyGems 2.x
|
|
||||||
Gem::Package.new(plugin_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
find_plugin_name = pkg.spec.name
|
|
||||||
version = pkg.spec.version
|
|
||||||
end
|
|
||||||
|
|
||||||
# Install the gem
|
# Install the gem
|
||||||
plugin_name_label = plugin_name
|
plugin_name_label = plugin_name
|
||||||
plugin_name_label += " --version '#{version}'" if version
|
plugin_name_label += " --version '#{version}'" if version
|
||||||
|
@ -56,7 +29,9 @@ module VagrantPlugins
|
||||||
plugin_name,
|
plugin_name,
|
||||||
version: version,
|
version: version,
|
||||||
require: entrypoint,
|
require: entrypoint,
|
||||||
sources: sources,)
|
sources: sources,
|
||||||
|
verbose: !!env[:plugin_verbose],
|
||||||
|
)
|
||||||
|
|
||||||
# Record it so we can uninstall if something goes wrong
|
# Record it so we can uninstall if something goes wrong
|
||||||
@installed_plugin_name = plugin_spec.name
|
@installed_plugin_name = plugin_spec.name
|
||||||
|
|
|
@ -10,12 +10,16 @@ module VagrantPlugins
|
||||||
include MixinInstallOpts
|
include MixinInstallOpts
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
options = {}
|
options = { verbose: false }
|
||||||
|
|
||||||
opts = OptionParser.new do |o|
|
opts = OptionParser.new do |o|
|
||||||
o.banner = "Usage: vagrant plugin install <name> [-h]"
|
o.banner = "Usage: vagrant plugin install <name> [-h]"
|
||||||
o.separator ""
|
o.separator ""
|
||||||
build_install_opts(o, options)
|
build_install_opts(o, options)
|
||||||
|
|
||||||
|
o.on("--verbose", "Enable verbose output for plugin installation") do |v|
|
||||||
|
options[:verbose] = v
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Parse the options
|
# Parse the options
|
||||||
|
@ -28,7 +32,8 @@ module VagrantPlugins
|
||||||
:plugin_entry_point => options[:entry_point],
|
:plugin_entry_point => options[:entry_point],
|
||||||
:plugin_version => options[:plugin_version],
|
:plugin_version => options[:plugin_version],
|
||||||
:plugin_sources => options[:plugin_sources],
|
:plugin_sources => options[:plugin_sources],
|
||||||
:plugin_name => argv[0]
|
:plugin_name => argv[0],
|
||||||
|
:plugin_verbose => options[:verbose]
|
||||||
})
|
})
|
||||||
|
|
||||||
# Success, exit status 0
|
# Success, exit status 0
|
||||||
|
|
Loading…
Reference in New Issue