commands/plugin: support installing from file
This commit is contained in:
parent
3f9fb2ef03
commit
86cab61c27
|
@ -1,3 +1,4 @@
|
|||
require "monitor"
|
||||
require "pathname"
|
||||
require "set"
|
||||
require "tempfile"
|
||||
|
@ -17,6 +18,8 @@ module Vagrant
|
|||
end
|
||||
|
||||
def initialize
|
||||
@monitor = Monitor.new
|
||||
|
||||
@gem_home = ENV["GEM_HOME"]
|
||||
@gem_path = ENV["GEM_PATH"]
|
||||
|
||||
|
@ -59,6 +62,41 @@ module Vagrant
|
|||
internal_install(plugins, nil)
|
||||
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.
|
||||
#
|
||||
# @param [Hash] plugins
|
||||
|
@ -84,6 +122,21 @@ module Vagrant
|
|||
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
|
||||
|
||||
# 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)
|
||||
# @return [Gem::Specification]
|
||||
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[name] = {
|
||||
"require" => opts[:require],
|
||||
|
@ -37,10 +44,18 @@ module Vagrant
|
|||
}
|
||||
|
||||
result = nil
|
||||
Vagrant::Bundler.instance.install(plugins).each do |spec|
|
||||
next if spec.name != name
|
||||
next if result && result.version >= spec.version
|
||||
result = spec
|
||||
install_lambda = lambda do
|
||||
Vagrant::Bundler.instance.install(plugins).each do |spec|
|
||||
next if spec.name != name
|
||||
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
|
||||
|
||||
# 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 "vagrant/plugin/manager"
|
||||
|
||||
|
@ -27,24 +18,6 @@ module VagrantPlugins
|
|||
sources = env[:plugin_sources]
|
||||
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
|
||||
plugin_name_label = plugin_name
|
||||
plugin_name_label += " --version '#{version}'" if version
|
||||
|
@ -56,7 +29,9 @@ module VagrantPlugins
|
|||
plugin_name,
|
||||
version: version,
|
||||
require: entrypoint,
|
||||
sources: sources,)
|
||||
sources: sources,
|
||||
verbose: !!env[:plugin_verbose],
|
||||
)
|
||||
|
||||
# Record it so we can uninstall if something goes wrong
|
||||
@installed_plugin_name = plugin_spec.name
|
||||
|
|
|
@ -10,12 +10,16 @@ module VagrantPlugins
|
|||
include MixinInstallOpts
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
options = { verbose: false }
|
||||
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant plugin install <name> [-h]"
|
||||
o.separator ""
|
||||
build_install_opts(o, options)
|
||||
|
||||
o.on("--verbose", "Enable verbose output for plugin installation") do |v|
|
||||
options[:verbose] = v
|
||||
end
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
|
@ -28,7 +32,8 @@ module VagrantPlugins
|
|||
:plugin_entry_point => options[:entry_point],
|
||||
:plugin_version => options[:plugin_version],
|
||||
:plugin_sources => options[:plugin_sources],
|
||||
:plugin_name => argv[0]
|
||||
:plugin_name => argv[0],
|
||||
:plugin_verbose => options[:verbose]
|
||||
})
|
||||
|
||||
# Success, exit status 0
|
||||
|
|
Loading…
Reference in New Issue