Merge pull request #10037 from chrisroberts/e-vagrant-plugins-local
Define project specific plugins
This commit is contained in:
commit
a993cbce4e
|
@ -44,7 +44,9 @@ argv.each_index do |i|
|
|||
|
||||
# Do not load plugins when performing plugin operations
|
||||
if arg == "plugin"
|
||||
opts[:vagrantfile_name] = ""
|
||||
if argv.none?{|a| a == "--local" } && !ENV["VAGRANT_LOCAL_PLUGINS_LOAD"]
|
||||
opts[:vagrantfile_name] = ""
|
||||
end
|
||||
ENV['VAGRANT_NO_PLUGINS'] = "1"
|
||||
# Only initialize plugins when listing installed plugins
|
||||
if argv[i+1] != "list"
|
||||
|
|
|
@ -3,6 +3,7 @@ require "vagrant/shared_helpers"
|
|||
require "rubygems"
|
||||
require "log4r"
|
||||
require "vagrant/util"
|
||||
require "vagrant/plugin/manager"
|
||||
|
||||
# Enable logging if it is requested. We do this before
|
||||
# anything else so that we can setup the output before
|
||||
|
@ -262,35 +263,6 @@ else
|
|||
global_logger.warn("resolv replacement has not been enabled!")
|
||||
end
|
||||
|
||||
# Setup the plugin manager and load any defined plugins
|
||||
require_relative "vagrant/plugin/manager"
|
||||
plugins = Vagrant::Plugin::Manager.instance.installed_plugins
|
||||
|
||||
global_logger.info("Plugins:")
|
||||
plugins.each do |plugin_name, plugin_info|
|
||||
installed_version = plugin_info["installed_gem_version"]
|
||||
version_constraint = plugin_info["gem_version"]
|
||||
installed_version = 'undefined' if installed_version.to_s.empty?
|
||||
version_constraint = '> 0' if version_constraint.to_s.empty?
|
||||
global_logger.info(
|
||||
" - #{plugin_name} = [installed: " \
|
||||
"#{installed_version} constraint: " \
|
||||
"#{version_constraint}]"
|
||||
)
|
||||
end
|
||||
|
||||
if Vagrant.plugins_init?
|
||||
begin
|
||||
Vagrant::Bundler.instance.init!(plugins)
|
||||
rescue StandardError, ScriptError => e
|
||||
global_logger.error("Plugin initialization error - #{e.class}: #{e}")
|
||||
e.backtrace.each do |backtrace_line|
|
||||
global_logger.debug(backtrace_line)
|
||||
end
|
||||
raise Vagrant::Errors::PluginInitError, message: e.to_s
|
||||
end
|
||||
end
|
||||
|
||||
# A lambda that knows how to load plugins from a single directory.
|
||||
plugin_load_proc = lambda do |directory|
|
||||
# We only care about directories
|
||||
|
@ -320,43 +292,3 @@ Vagrant.source_root.join("plugins").children(true).each do |directory|
|
|||
# Otherwise, attempt to load from sub-directories
|
||||
directory.children(true).each(&plugin_load_proc)
|
||||
end
|
||||
|
||||
# If we have plugins enabled, then load those
|
||||
if Vagrant.plugins_enabled?
|
||||
begin
|
||||
global_logger.info("Loading plugins!")
|
||||
plugins.each do |plugin_name, plugin_info|
|
||||
if plugin_info["require"].to_s.empty?
|
||||
begin
|
||||
global_logger.info("Loading plugin `#{plugin_name}` with default require: `#{plugin_name}`")
|
||||
require plugin_name
|
||||
rescue LoadError => err
|
||||
if plugin_name.include?("-")
|
||||
plugin_slash = plugin_name.gsub("-", "/")
|
||||
global_logger.error("Failed to load plugin `#{plugin_name}` with default require. - #{err.class}: #{err}")
|
||||
global_logger.info("Loading plugin `#{plugin_name}` with slash require: `#{plugin_slash}`")
|
||||
require plugin_slash
|
||||
else
|
||||
raise
|
||||
end
|
||||
end
|
||||
else
|
||||
global_logger.debug("Loading plugin `#{plugin_name}` with custom require: `#{plugin_info["require"]}`")
|
||||
require plugin_info["require"]
|
||||
end
|
||||
global_logger.debug("Successfully loaded plugin `#{plugin_name}`.")
|
||||
end
|
||||
if defined?(::Bundler)
|
||||
global_logger.debug("Bundler detected in use. Loading `:plugins` group.")
|
||||
::Bundler.require(:plugins)
|
||||
end
|
||||
rescue ScriptError, StandardError => err
|
||||
global_logger.error("Plugin loading error: #{err.class} - #{err}")
|
||||
err.backtrace.each do |backtrace_line|
|
||||
global_logger.debug(backtrace_line)
|
||||
end
|
||||
raise Vagrant::Errors::PluginLoadError, message: err.to_s
|
||||
end
|
||||
else
|
||||
global_logger.debug("Plugin loading is currently disabled.")
|
||||
end
|
||||
|
|
|
@ -32,22 +32,42 @@ module Vagrant
|
|||
@bundler ||= self.new
|
||||
end
|
||||
|
||||
# @return [Pathname] Global plugin path
|
||||
attr_reader :plugin_gem_path
|
||||
# @return [Pathname] Vagrant environment specific plugin path
|
||||
attr_reader :env_plugin_gem_path
|
||||
|
||||
def initialize
|
||||
@plugin_gem_path = Vagrant.user_data_path.join("gems", RUBY_VERSION).freeze
|
||||
@logger = Log4r::Logger.new("vagrant::bundler")
|
||||
end
|
||||
|
||||
# Enable Vagrant environment specific plugins at given data path
|
||||
#
|
||||
# @param [Pathname] Path to Vagrant::Environment data directory
|
||||
# @return [Pathname] Path to environment specific gem directory
|
||||
def environment_path=(env_data_path)
|
||||
@env_plugin_gem_path = env_data_path.join("plugins", "gems", RUBY_VERSION).freeze
|
||||
end
|
||||
|
||||
# Initializes Bundler and the various gem paths so that we can begin
|
||||
# loading gems. This must only be called once.
|
||||
# loading gems.
|
||||
def init!(plugins, repair=false)
|
||||
if !@initial_specifications
|
||||
@initial_specifications = Gem::Specification.find_all{true}
|
||||
else
|
||||
Gem::Specification.all = @initial_specifications
|
||||
Gem::Specification.reset
|
||||
end
|
||||
|
||||
# Add HashiCorp RubyGems source
|
||||
Gem.sources << HASHICORP_GEMSTORE
|
||||
if !Gem.sources.include?(HASHICORP_GEMSTORE)
|
||||
Gem.sources << HASHICORP_GEMSTORE
|
||||
end
|
||||
|
||||
# Generate dependencies for all registered plugins
|
||||
plugin_deps = plugins.map do |name, info|
|
||||
Gem::Dependency.new(name, info['gem_version'].to_s.empty? ? '> 0' : info['gem_version'])
|
||||
Gem::Dependency.new(name, info['installed_gem_version'].to_s.empty? ? '> 0' : info['installed_gem_version'])
|
||||
end
|
||||
|
||||
@logger.debug("Current generated plugin dependency list: #{plugin_deps}")
|
||||
|
@ -78,7 +98,7 @@ module Vagrant
|
|||
# Activate the gems
|
||||
activate_solution(solution)
|
||||
|
||||
full_vagrant_spec_list = Gem::Specification.find_all{true} +
|
||||
full_vagrant_spec_list = @initial_specifications +
|
||||
solution.map(&:full_spec)
|
||||
|
||||
if(defined?(::Bundler))
|
||||
|
@ -91,6 +111,7 @@ module Vagrant
|
|||
end
|
||||
|
||||
Gem::Specification.reset
|
||||
nil
|
||||
end
|
||||
|
||||
# Removes any temporary files created by init
|
||||
|
@ -101,9 +122,10 @@ module Vagrant
|
|||
# Installs the list of plugins.
|
||||
#
|
||||
# @param [Hash] plugins
|
||||
# @param [Boolean] env_local Environment local plugin install
|
||||
# @return [Array<Gem::Specification>]
|
||||
def install(plugins, local=false)
|
||||
internal_install(plugins, nil, local: local)
|
||||
def install(plugins, env_local=false)
|
||||
internal_install(plugins, nil, env_local: env_local)
|
||||
end
|
||||
|
||||
# Installs a local '*.gem' file so that Bundler can find it.
|
||||
|
@ -120,7 +142,7 @@ module Vagrant
|
|||
}
|
||||
}
|
||||
@logger.debug("Installing local plugin - #{plugin_info}")
|
||||
internal_install(plugin_info, {})
|
||||
internal_install(plugin_info, nil, env_local: opts[:env_local])
|
||||
plugin_source.spec
|
||||
end
|
||||
|
||||
|
@ -129,14 +151,14 @@ module Vagrant
|
|||
# @param [Hash] plugins
|
||||
# @param [Array<String>] specific Specific plugin names to update. If
|
||||
# empty or nil, all plugins will be updated.
|
||||
def update(plugins, specific)
|
||||
def update(plugins, specific, **opts)
|
||||
specific ||= []
|
||||
update = {gems: specific.empty? ? true : specific}
|
||||
update = opts.merge({gems: specific.empty? ? true : specific})
|
||||
internal_install(plugins, update)
|
||||
end
|
||||
|
||||
# Clean removes any unused gems.
|
||||
def clean(plugins)
|
||||
def clean(plugins, **opts)
|
||||
@logger.debug("Cleaning Vagrant plugins of stale gems.")
|
||||
# Generate dependencies for all registered plugins
|
||||
plugin_deps = plugins.map do |name, info|
|
||||
|
@ -163,6 +185,13 @@ module Vagrant
|
|||
Gem::Specification.load(spec_path)
|
||||
end
|
||||
|
||||
# Include environment specific specification if enabled
|
||||
if env_plugin_gem_path
|
||||
plugin_specs += Dir.glob(env_plugin_gem_path.join('specifications/*.gemspec').to_s).map do |spec_path|
|
||||
Gem::Specification.load(spec_path)
|
||||
end
|
||||
end
|
||||
|
||||
@logger.debug("Generating current plugin state solution set.")
|
||||
|
||||
# Resolve the request set to ensure proper activation order
|
||||
|
@ -171,11 +200,27 @@ module Vagrant
|
|||
solution_full_names = solution_specs.map(&:full_name)
|
||||
|
||||
# Find all specs installed to plugins directory that are not
|
||||
# found within the solution set
|
||||
# found within the solution set.
|
||||
plugin_specs.delete_if do |spec|
|
||||
solution_full_names.include?(spec.full_name)
|
||||
end
|
||||
|
||||
if env_plugin_gem_path
|
||||
# If we are cleaning locally, remove any global specs. If
|
||||
# not, remove any local specs
|
||||
if opts[:env_local]
|
||||
@logger.debug("Removing specifications that are not environment local")
|
||||
plugin_specs.delete_if do |spec|
|
||||
spec.full_gem_path.to_s.include?(plugin_gem_path.realpath.to_s)
|
||||
end
|
||||
else
|
||||
@logger.debug("Removing specifications that are environment local")
|
||||
plugin_specs.delete_if do |spec|
|
||||
spec.full_gem_path.to_s.include?(env_plugin_gem_path.realpath.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@logger.debug("Specifications to be removed - #{plugin_specs.map(&:full_name)}")
|
||||
|
||||
# Now delete all unused specs
|
||||
|
@ -318,18 +363,37 @@ module Vagrant
|
|||
# as we know the dependencies are satisfied and it will attempt to validate a gem's
|
||||
# dependencies are satisfied by gems in the install directory (which will likely not
|
||||
# be true)
|
||||
result = request_set.install_into(plugin_gem_path.to_s, true,
|
||||
install_path = extra[:env_local] ? env_plugin_gem_path : plugin_gem_path
|
||||
result = request_set.install_into(install_path.to_s, true,
|
||||
ignore_dependencies: true,
|
||||
prerelease: Vagrant.prerelease?,
|
||||
wrappers: true
|
||||
)
|
||||
result = result.map(&:full_spec)
|
||||
result.each do |spec|
|
||||
existing_paths = $LOAD_PATH.find_all{|s| s.include?(spec.full_name) }
|
||||
if !existing_paths.empty?
|
||||
@logger.debug("Removing existing LOAD_PATHs for #{spec.full_name} - " +
|
||||
existing_paths.join(", "))
|
||||
existing_paths.each{|s| $LOAD_PATH.delete(s) }
|
||||
end
|
||||
spec.full_require_paths.each do |r_path|
|
||||
if !$LOAD_PATH.include?(r_path)
|
||||
@logger.debug("Adding path to LOAD_PATH - #{r_path}")
|
||||
$LOAD_PATH.unshift(r_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
# Generate the composite resolver set totally all of vagrant (builtin + plugin set)
|
||||
def generate_vagrant_set
|
||||
Gem::Resolver.compose_sets(generate_builtin_set, generate_plugin_set)
|
||||
sets = [generate_builtin_set, generate_plugin_set]
|
||||
if env_plugin_gem_path && env_plugin_gem_path.exist?
|
||||
sets << generate_plugin_set(env_plugin_gem_path)
|
||||
end
|
||||
Gem::Resolver.compose_sets(*sets)
|
||||
end
|
||||
|
||||
# @return [Array<[Gem::Specification, String]>] spec and directory pairs
|
||||
|
@ -387,10 +451,16 @@ module Vagrant
|
|||
|
||||
# Generate the plugin resolver set. Optionally provide specification names (short or
|
||||
# full) that should be ignored
|
||||
def generate_plugin_set(skip=[])
|
||||
#
|
||||
# @param [Pathname] path to plugins
|
||||
# @param [Array<String>] gems to skip
|
||||
# @return [PluginSet]
|
||||
def generate_plugin_set(*args)
|
||||
plugin_path = args.detect{|i| i.is_a?(Pathname) } || plugin_gem_path
|
||||
skip = args.detect{|i| i.is_a?(Array) } || []
|
||||
plugin_set = PluginSet.new
|
||||
@logger.debug("Generating new plugin set instance. Skip gems - #{skip}")
|
||||
Dir.glob(plugin_gem_path.join('specifications/*.gemspec').to_s).each do |spec_path|
|
||||
Dir.glob(plugin_path.join('specifications/*.gemspec').to_s).each do |spec_path|
|
||||
spec = Gem::Specification.load(spec_path)
|
||||
desired_spec_path = File.join(spec.gem_dir, "#{spec.name}.gemspec")
|
||||
# Vendor set requires the spec to be within the gem directory. Some gems will package their
|
||||
|
|
|
@ -8,6 +8,7 @@ require 'log4r'
|
|||
|
||||
require 'vagrant/util/file_mode'
|
||||
require 'vagrant/util/platform'
|
||||
require 'vagrant/util/hash_with_indifferent_access'
|
||||
require "vagrant/util/silence_warnings"
|
||||
require "vagrant/vagrantfile"
|
||||
require "vagrant/version"
|
||||
|
@ -146,6 +147,7 @@ module Vagrant
|
|||
if opts[:local_data_path]
|
||||
@local_data_path = Pathname.new(File.expand_path(opts[:local_data_path], @cwd))
|
||||
end
|
||||
|
||||
@logger.debug("Effective local data path: #{@local_data_path}")
|
||||
|
||||
# If we have a root path, load the ".vagrantplugins" file.
|
||||
|
@ -163,6 +165,19 @@ module Vagrant
|
|||
@default_private_key_path = @home_path.join("insecure_private_key")
|
||||
copy_insecure_private_key
|
||||
|
||||
# Initialize localized plugins
|
||||
plugins = Vagrant::Plugin::Manager.instance.localize!(self)
|
||||
|
||||
if !vagrantfile.config.vagrant.plugins.empty?
|
||||
plugins = process_configured_plugins
|
||||
end
|
||||
|
||||
# Load any environment local plugins
|
||||
Vagrant::Plugin::Manager.instance.load_plugins(plugins)
|
||||
|
||||
plugins = Vagrant::Plugin::Manager.instance.globalize!
|
||||
Vagrant::Plugin::Manager.instance.load_plugins(plugins)
|
||||
|
||||
# Call the hooks that does not require configurations to be loaded
|
||||
# by using a "clean" action runner
|
||||
hook(:environment_plugins_loaded, runner: Action::Runner.new(env: self))
|
||||
|
@ -898,6 +913,64 @@ module Vagrant
|
|||
|
||||
protected
|
||||
|
||||
# Check for any local plugins defined within the Vagrantfile. If
|
||||
# found, validate they are available. If they are not available,
|
||||
# request to install them, or raise an exception
|
||||
#
|
||||
# @return [Hash] plugin list for loading
|
||||
def process_configured_plugins
|
||||
return if !Vagrant.plugins_enabled?
|
||||
errors = vagrantfile.config.vagrant.validate(nil)
|
||||
if !errors["vagrant"].empty?
|
||||
raise Errors::ConfigInvalid,
|
||||
errors: Util::TemplateRenderer.render(
|
||||
"config/validation_failed",
|
||||
errors: errors)
|
||||
end
|
||||
# Check if defined plugins are installed
|
||||
installed = Plugin::Manager.instance.installed_plugins
|
||||
needs_install = []
|
||||
config_plugins = vagrantfile.config.vagrant.plugins
|
||||
config_plugins.each do |name, info|
|
||||
if !installed[name]
|
||||
needs_install << name
|
||||
end
|
||||
end
|
||||
if !needs_install.empty?
|
||||
ui.warn(I18n.t("vagrant.plugins.local.uninstalled_plugins",
|
||||
plugins: needs_install.sort.join(", ")))
|
||||
if !Vagrant.auto_install_local_plugins?
|
||||
answer = nil
|
||||
until ["y", "n"].include?(answer)
|
||||
answer = ui.ask(I18n.t("vagrant.plugins.local.request_plugin_install") + " [N]: ")
|
||||
answer.strip!.downcase!
|
||||
answer = "n" if answer.to_s.empty?
|
||||
end
|
||||
if answer == "n"
|
||||
raise Errors::PluginMissingLocalError,
|
||||
plugins: needs_install.sort.join(", ")
|
||||
end
|
||||
end
|
||||
needs_install.each do |name|
|
||||
pconfig = Util::HashWithIndifferentAccess.new(config_plugins[name])
|
||||
ui.info(I18n.t("vagrant.commands.plugin.installing", name: name))
|
||||
|
||||
options = {sources: Vagrant::Bundler::DEFAULT_GEM_SOURCES.dup, env_local: true}
|
||||
options[:sources] = pconfig[:sources] if pconfig[:sources]
|
||||
options[:require] = pconfig[:entry_point] if pconfig[:entry_point]
|
||||
options[:version] = pconfig[:version] if pconfig[:version]
|
||||
|
||||
spec = Plugin::Manager.instance.install_plugin(name, options)
|
||||
|
||||
ui.info(I18n.t("vagrant.commands.plugin.installed",
|
||||
name: spec.name, version: spec.version.to_s))
|
||||
end
|
||||
ui.info("\n")
|
||||
Vagrant::Plugin::Manager.instance.localize!(self)
|
||||
end
|
||||
Vagrant::Plugin::Manager.instance.local_file.installed_plugins
|
||||
end
|
||||
|
||||
# This method copies the private key into the home directory if it
|
||||
# doesn't already exist.
|
||||
#
|
||||
|
|
|
@ -640,6 +640,14 @@ module Vagrant
|
|||
error_key(:plugin_source_error)
|
||||
end
|
||||
|
||||
class PluginNoLocalError < VagrantError
|
||||
error_key(:plugin_no_local_error)
|
||||
end
|
||||
|
||||
class PluginMissingLocalError < VagrantError
|
||||
error_key(:plugin_missing_local_error)
|
||||
end
|
||||
|
||||
class PushesNotDefined < VagrantError
|
||||
error_key(:pushes_not_defined)
|
||||
end
|
||||
|
|
|
@ -27,13 +27,78 @@ module Vagrant
|
|||
@instance ||= self.new(user_plugins_file)
|
||||
end
|
||||
|
||||
attr_reader :user_file
|
||||
attr_reader :system_file
|
||||
attr_reader :local_file
|
||||
|
||||
# @param [Pathname] user_file
|
||||
def initialize(user_file)
|
||||
@logger = Log4r::Logger.new("vagrant::plugin::manager")
|
||||
@user_file = StateFile.new(user_file)
|
||||
|
||||
system_path = self.class.system_plugins_file
|
||||
@system_file = nil
|
||||
@system_file = StateFile.new(system_path) if system_path && system_path.file?
|
||||
|
||||
@local_file = nil
|
||||
end
|
||||
|
||||
# Enable global plugins
|
||||
#
|
||||
# @return [Hash] list of plugins
|
||||
def globalize!
|
||||
@logger.debug("Enabling globalized plugins")
|
||||
plugins = installed_plugins
|
||||
bundler_init(plugins)
|
||||
plugins
|
||||
end
|
||||
|
||||
# Enable environment local plugins
|
||||
#
|
||||
# @param [Environment] env Vagrant environment
|
||||
# @return [Hash] list of plugins
|
||||
def localize!(env)
|
||||
if env.local_data_path
|
||||
@logger.debug("Enabling localized plugins")
|
||||
@local_file = StateFile.new(env.local_data_path.join("plugins.json"))
|
||||
Vagrant::Bundler.instance.environment_path = env.local_data_path
|
||||
plugins = local_file.installed_plugins
|
||||
bundler_init(plugins)
|
||||
plugins
|
||||
end
|
||||
end
|
||||
|
||||
# Initialize bundler with given plugins
|
||||
#
|
||||
# @param [Hash] plugins List of plugins
|
||||
# @return [nil]
|
||||
def bundler_init(plugins)
|
||||
if !Vagrant.plugins_init?
|
||||
@logger.warn("Plugin initialization is disabled")
|
||||
return nil
|
||||
end
|
||||
|
||||
@logger.info("Plugins:")
|
||||
plugins.each do |plugin_name, plugin_info|
|
||||
installed_version = plugin_info["installed_gem_version"]
|
||||
version_constraint = plugin_info["gem_version"]
|
||||
installed_version = 'undefined' if installed_version.to_s.empty?
|
||||
version_constraint = '> 0' if version_constraint.to_s.empty?
|
||||
@logger.info(
|
||||
" - #{plugin_name} = [installed: " \
|
||||
"#{installed_version} constraint: " \
|
||||
"#{version_constraint}]"
|
||||
)
|
||||
end
|
||||
begin
|
||||
Vagrant::Bundler.instance.init!(plugins)
|
||||
rescue StandardError, ScriptError => err
|
||||
@logger.error("Plugin initialization error - #{err.class}: #{err}")
|
||||
err.backtrace.each do |backtrace_line|
|
||||
@logger.debug(backtrace_line)
|
||||
end
|
||||
raise Vagrant::Errors::PluginInitError, message: err.to_s
|
||||
end
|
||||
end
|
||||
|
||||
# Installs another plugin into our gem directory.
|
||||
|
@ -41,7 +106,10 @@ module Vagrant
|
|||
# @param [String] name Name of the plugin (gem)
|
||||
# @return [Gem::Specification]
|
||||
def install_plugin(name, **opts)
|
||||
local = false
|
||||
if opts[:env_local] && @local_file.nil?
|
||||
raise Errors::PluginNoLocalError
|
||||
end
|
||||
|
||||
if name =~ /\.gem$/
|
||||
# If this is a gem file, then we install that gem locally.
|
||||
local_spec = Vagrant::Bundler.instance.install_local(name, opts)
|
||||
|
@ -59,7 +127,7 @@ module Vagrant
|
|||
if local_spec.nil?
|
||||
result = nil
|
||||
install_lambda = lambda do
|
||||
Vagrant::Bundler.instance.install(plugins, local).each do |spec|
|
||||
Vagrant::Bundler.instance.install(plugins, opts[:env_local]).each do |spec|
|
||||
next if spec.name != name
|
||||
next if result && result.version >= spec.version
|
||||
result = spec
|
||||
|
@ -75,18 +143,20 @@ module Vagrant
|
|||
result = local_spec
|
||||
end
|
||||
# Add the plugin to the state file
|
||||
@user_file.add_plugin(
|
||||
plugin_file = opts[:env_local] ? @local_file : @user_file
|
||||
plugin_file.add_plugin(
|
||||
result.name,
|
||||
version: opts[:version],
|
||||
require: opts[:require],
|
||||
sources: opts[:sources],
|
||||
env_local: !!opts[:env_local],
|
||||
installed_gem_version: result.version.to_s
|
||||
)
|
||||
|
||||
# After install clean plugin gems to remove any cruft. This is useful
|
||||
# for removing outdated dependencies or other versions of an installed
|
||||
# plugin if the plugin is upgraded/downgraded
|
||||
Vagrant::Bundler.instance.clean(installed_plugins)
|
||||
Vagrant::Bundler.instance.clean(installed_plugins, local: !!opts[:local])
|
||||
result
|
||||
rescue Gem::GemNotFoundException
|
||||
raise Errors::PluginGemNotFound, name: name
|
||||
|
@ -97,7 +167,7 @@ module Vagrant
|
|||
# Uninstalls the plugin with the given name.
|
||||
#
|
||||
# @param [String] name
|
||||
def uninstall_plugin(name)
|
||||
def uninstall_plugin(name, **opts)
|
||||
if @system_file
|
||||
if !@user_file.has_plugin?(name) && @system_file.has_plugin?(name)
|
||||
raise Errors::PluginUninstallSystem,
|
||||
|
@ -105,7 +175,18 @@ module Vagrant
|
|||
end
|
||||
end
|
||||
|
||||
@user_file.remove_plugin(name)
|
||||
if opts[:env_local] && @local_file.nil?
|
||||
raise Errors::PluginNoLocalError
|
||||
end
|
||||
|
||||
plugin_file = opts[:env_local] ? @local_file : @user_file
|
||||
|
||||
if !plugin_file.has_plugin?(name)
|
||||
raise Errors::PluginNotInstalled,
|
||||
name: name
|
||||
end
|
||||
|
||||
plugin_file.remove_plugin(name)
|
||||
|
||||
# Clean the environment, removing any old plugins
|
||||
Vagrant::Bundler.instance.clean(installed_plugins)
|
||||
|
@ -114,9 +195,15 @@ module Vagrant
|
|||
end
|
||||
|
||||
# Updates all or a specific set of plugins.
|
||||
def update_plugins(specific)
|
||||
result = Vagrant::Bundler.instance.update(installed_plugins, specific)
|
||||
installed_plugins.each do |name, info|
|
||||
def update_plugins(specific, **opts)
|
||||
if opts[:env_local] && @local_file.nil?
|
||||
raise Errors::PluginNoLocalError
|
||||
end
|
||||
|
||||
plugin_file = opts[:env_local] ? @local_file : @user_file
|
||||
|
||||
result = Vagrant::Bundler.instance.update(plugin_file.installed_plugins, specific)
|
||||
plugin_file.installed_plugins.each do |name, info|
|
||||
matching_spec = result.detect{|s| s.name == name}
|
||||
info = Hash[
|
||||
info.map do |key, value|
|
||||
|
@ -124,7 +211,7 @@ module Vagrant
|
|||
end
|
||||
]
|
||||
if matching_spec
|
||||
@user_file.add_plugin(name, **info.merge(
|
||||
plugin_file.add_plugin(name, **info.merge(
|
||||
version: "> 0",
|
||||
installed_gem_version: matching_spec.version.to_s
|
||||
))
|
||||
|
@ -148,6 +235,11 @@ module Vagrant
|
|||
end
|
||||
plugin_list = Util::DeepMerge.deep_merge(system, @user_file.installed_plugins)
|
||||
|
||||
if @local_file
|
||||
plugin_list = Util::DeepMerge.deep_merge(plugin_list,
|
||||
@local_file.installed_plugins)
|
||||
end
|
||||
|
||||
# Sort plugins by name
|
||||
Hash[
|
||||
plugin_list.map{|plugin_name, plugin_info|
|
||||
|
@ -191,6 +283,58 @@ module Vagrant
|
|||
|
||||
installed_map.values
|
||||
end
|
||||
|
||||
# Loads the requested plugins into the Vagrant runtime
|
||||
#
|
||||
# @param [Hash] plugins List of plugins to load
|
||||
# @return [nil]
|
||||
def load_plugins(plugins)
|
||||
if !Vagrant.plugins_enabled?
|
||||
@logger.warn("Plugin loading is disabled")
|
||||
return
|
||||
end
|
||||
|
||||
if plugins.nil?
|
||||
@logger.debug("No plugins provided for loading")
|
||||
return
|
||||
end
|
||||
|
||||
begin
|
||||
@logger.info("Loading plugins...")
|
||||
plugins.each do |plugin_name, plugin_info|
|
||||
if plugin_info["require"].to_s.empty?
|
||||
begin
|
||||
@logger.info("Loading plugin `#{plugin_name}` with default require: `#{plugin_name}`")
|
||||
require plugin_name
|
||||
rescue LoadError => err
|
||||
if plugin_name.include?("-")
|
||||
plugin_slash = plugin_name.gsub("-", "/")
|
||||
@logger.error("Failed to load plugin `#{plugin_name}` with default require. - #{err.class}: #{err}")
|
||||
@logger.info("Loading plugin `#{plugin_name}` with slash require: `#{plugin_slash}`")
|
||||
require plugin_slash
|
||||
else
|
||||
raise
|
||||
end
|
||||
end
|
||||
else
|
||||
@logger.debug("Loading plugin `#{plugin_name}` with custom require: `#{plugin_info["require"]}`")
|
||||
require plugin_info["require"]
|
||||
end
|
||||
@logger.debug("Successfully loaded plugin `#{plugin_name}`.")
|
||||
end
|
||||
if defined?(::Bundler)
|
||||
@logger.debug("Bundler detected in use. Loading `:plugins` group.")
|
||||
::Bundler.require(:plugins)
|
||||
end
|
||||
rescue ScriptError, StandardError => err
|
||||
@logger.error("Plugin loading error: #{err.class} - #{err}")
|
||||
err.backtrace.each do |backtrace_line|
|
||||
@logger.debug(backtrace_line)
|
||||
end
|
||||
raise Vagrant::Errors::PluginLoadError, message: err.to_s
|
||||
end
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,6 +7,10 @@ module Vagrant
|
|||
# This is a helper to deal with the plugin state file that Vagrant
|
||||
# uses to track what plugins are installed and activated and such.
|
||||
class StateFile
|
||||
|
||||
# @return [Pathname] path to file
|
||||
attr_reader :path
|
||||
|
||||
def initialize(path)
|
||||
@path = path
|
||||
|
||||
|
@ -36,7 +40,8 @@ module Vagrant
|
|||
"gem_version" => opts[:version] || "",
|
||||
"require" => opts[:require] || "",
|
||||
"sources" => opts[:sources] || [],
|
||||
"installed_gem_version" => opts[:installed_gem_version]
|
||||
"installed_gem_version" => opts[:installed_gem_version],
|
||||
"env_local" => !!opts[:env_local]
|
||||
}
|
||||
|
||||
save!
|
||||
|
|
|
@ -130,6 +130,18 @@ module Vagrant
|
|||
end
|
||||
end
|
||||
|
||||
# Automatically install locally defined plugins instead of
|
||||
# waiting for user confirmation.
|
||||
#
|
||||
# @return [Boolean]
|
||||
def self.auto_install_local_plugins?
|
||||
if ENV["VAGRANT_INSTALL_LOCAL_PLUGINS"]
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
# Use Ruby Resolv in place of libc
|
||||
#
|
||||
# @return [boolean] enabled or not
|
||||
|
|
|
@ -41,6 +41,13 @@ module VagrantPlugins
|
|||
end
|
||||
end
|
||||
|
||||
# This middleware sequence will repair installed local plugins.
|
||||
def self.action_repair_local
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
b.use RepairPluginsLocal
|
||||
end
|
||||
end
|
||||
|
||||
# This middleware sequence will uninstall a plugin.
|
||||
def self.action_uninstall
|
||||
Vagrant::Action::Builder.new.tap do |b|
|
||||
|
@ -64,6 +71,7 @@ module VagrantPlugins
|
|||
autoload :ListPlugins, action_root.join("list_plugins")
|
||||
autoload :PluginExistsCheck, action_root.join("plugin_exists_check")
|
||||
autoload :RepairPlugins, action_root.join("repair_plugins")
|
||||
autoload :RepairPluginsLocal, action_root.join("repair_plugins")
|
||||
autoload :UninstallPlugin, action_root.join("uninstall_plugin")
|
||||
autoload :UpdateGems, action_root.join("update_gems")
|
||||
end
|
||||
|
|
|
@ -42,17 +42,25 @@ module VagrantPlugins
|
|||
end
|
||||
|
||||
if !abort_action
|
||||
plugins_json = File.join(env[:home_path], "plugins.json")
|
||||
plugins_gems = env[:gems_path]
|
||||
files = []
|
||||
dirs = []
|
||||
|
||||
if File.exist?(plugins_json)
|
||||
FileUtils.rm(plugins_json)
|
||||
# Do not include global paths if local only
|
||||
if !env[:env_local_only] || env[:global_only]
|
||||
files << Vagrant::Plugin::Manager.instance.user_file.path
|
||||
dirs << Vagrant::Bundler.instance.plugin_gem_path
|
||||
end
|
||||
|
||||
if File.directory?(plugins_gems)
|
||||
FileUtils.rm_rf(plugins_gems)
|
||||
# Add local paths if they exist
|
||||
if Vagrant::Plugin::Manager.instance.local_file && (env[:env_local_only] || !env[:global_only])
|
||||
files << Vagrant::Plugin::Manager.instance.local_file.path
|
||||
dirs << Vagrant::Bundler.instance.env_plugin_gem_path
|
||||
end
|
||||
|
||||
# Expunge files and directories
|
||||
files.find_all(&:exist?).map(&:delete)
|
||||
dirs.find_all(&:exist?).map(&:rmtree)
|
||||
|
||||
env[:ui].info(I18n.t("vagrant.commands.plugin.expunge_complete"))
|
||||
|
||||
@app.call(env)
|
||||
|
|
|
@ -18,6 +18,7 @@ module VagrantPlugins
|
|||
plugin_name = env[:plugin_name]
|
||||
sources = env[:plugin_sources]
|
||||
version = env[:plugin_version]
|
||||
env_local = env[:plugin_env_local]
|
||||
|
||||
# Install the gem
|
||||
plugin_name_label = plugin_name
|
||||
|
@ -28,10 +29,11 @@ module VagrantPlugins
|
|||
manager = Vagrant::Plugin::Manager.instance
|
||||
plugin_spec = manager.install_plugin(
|
||||
plugin_name,
|
||||
version: version,
|
||||
require: entrypoint,
|
||||
sources: sources,
|
||||
verbose: !!env[:plugin_verbose],
|
||||
version: version,
|
||||
require: entrypoint,
|
||||
sources: sources,
|
||||
verbose: !!env[:plugin_verbose],
|
||||
env_local: env_local
|
||||
)
|
||||
|
||||
# Record it so we can uninstall if something goes wrong
|
||||
|
|
|
@ -35,13 +35,16 @@ module VagrantPlugins
|
|||
spec = specs[plugin_name]
|
||||
next if spec.nil?
|
||||
|
||||
system = ""
|
||||
system = ", system" if plugin && plugin["system"]
|
||||
env[:ui].info "#{spec.name} (#{spec.version}#{system})"
|
||||
meta = ", global"
|
||||
if plugin
|
||||
meta = ", system" if plugin["system"]
|
||||
meta = ", local" if plugin["env_local"]
|
||||
end
|
||||
env[:ui].info "#{spec.name} (#{spec.version}#{meta})"
|
||||
env[:ui].machine("plugin-name", spec.name)
|
||||
env[:ui].machine(
|
||||
"plugin-version",
|
||||
"#{spec.version}#{system}",
|
||||
"#{spec.version}#{meta}",
|
||||
target: spec.name)
|
||||
|
||||
if plugin["gem_version"] && plugin["gem_version"] != ""
|
||||
|
|
|
@ -19,11 +19,13 @@ module VagrantPlugins
|
|||
|
||||
def call(env)
|
||||
env[:ui].info(I18n.t("vagrant.commands.plugin.repairing"))
|
||||
plugins = Vagrant::Plugin::Manager.instance.installed_plugins
|
||||
plugins = Vagrant::Plugin::Manager.instance.globalize!
|
||||
begin
|
||||
ENV["VAGRANT_DISABLE_PLUGIN_INIT"] = nil
|
||||
Vagrant::Bundler.instance.init!(plugins, :repair)
|
||||
ENV["VAGRANT_DISABLE_PLUGIN_INIT"] = "1"
|
||||
env[:ui].info(I18n.t("vagrant.commands.plugin.repair_complete"))
|
||||
rescue Exception => e
|
||||
rescue => e
|
||||
@logger.error("Failed to repair user installed plugins: #{e.class} - #{e}")
|
||||
e.backtrace.each do |backtrace_line|
|
||||
@logger.debug(backtrace_line)
|
||||
|
@ -34,6 +36,29 @@ module VagrantPlugins
|
|||
@app.call(env)
|
||||
end
|
||||
end
|
||||
|
||||
class RepairPluginsLocal
|
||||
def initialize(app, env)
|
||||
@app = app
|
||||
@logger = Log4r::Logger.new("vagrant::plugins::plugincommand::repair_local")
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env[:ui].info(I18n.t("vagrant.commands.plugin.repairing_local"))
|
||||
Vagrant::Plugin::Manager.instance.localize!(env[:env]).each_pair do |pname, pinfo|
|
||||
env[:env].action_runner.run(Action.action_install,
|
||||
plugin_name: pname,
|
||||
plugin_entry_point: pinfo["require"],
|
||||
plugin_sources: pinfo["sources"],
|
||||
plugin_version: pinfo["gem_version"],
|
||||
plugin_env_local: true
|
||||
)
|
||||
end
|
||||
env[:ui].info(I18n.t("vagrant.commands.plugin.repair_local_complete"))
|
||||
# Continue
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,7 +15,7 @@ module VagrantPlugins
|
|||
name: env[:plugin_name]))
|
||||
|
||||
manager = Vagrant::Plugin::Manager.instance
|
||||
manager.uninstall_plugin(env[:plugin_name])
|
||||
manager.uninstall_plugin(env[:plugin_name], env_local: env[:env_local])
|
||||
|
||||
@app.call(env)
|
||||
end
|
||||
|
|
|
@ -16,6 +16,18 @@ module VagrantPlugins
|
|||
options[:force] = force
|
||||
end
|
||||
|
||||
o.on("--local", "Include plugins from local project for expunge") do |l|
|
||||
options[:env_local] = l
|
||||
end
|
||||
|
||||
o.on("--local-only", "Only expunge local project plugins") do |l|
|
||||
options[:env_local_only] = l
|
||||
end
|
||||
|
||||
o.on("--global-only", "Only expunge global plugins") do |l|
|
||||
options[:global_only] = l
|
||||
end
|
||||
|
||||
o.on("--reinstall", "Reinstall current plugins after expunge") do |reinstall|
|
||||
options[:reinstall] = reinstall
|
||||
end
|
||||
|
|
|
@ -9,6 +9,8 @@ module VagrantPlugins
|
|||
class Install < Base
|
||||
include MixinInstallOpts
|
||||
|
||||
LOCAL_INSTALL_PAUSE = 3
|
||||
|
||||
def execute
|
||||
options = { verbose: false }
|
||||
|
||||
|
@ -17,6 +19,10 @@ module VagrantPlugins
|
|||
o.separator ""
|
||||
build_install_opts(o, options)
|
||||
|
||||
o.on("--local", "Install plugin for local project only") do |l|
|
||||
options[:env_local] = l
|
||||
end
|
||||
|
||||
o.on("--verbose", "Enable verbose output for plugin installation") do |v|
|
||||
options[:verbose] = v
|
||||
end
|
||||
|
@ -25,17 +31,51 @@ module VagrantPlugins
|
|||
# Parse the options
|
||||
argv = parse_options(opts)
|
||||
return if !argv
|
||||
raise Vagrant::Errors::CLIInvalidUsage, help: opts.help.chomp if argv.length < 1
|
||||
|
||||
# Install the gem
|
||||
argv.each do |name|
|
||||
action(Action.action_install, {
|
||||
plugin_entry_point: options[:entry_point],
|
||||
plugin_version: options[:plugin_version],
|
||||
plugin_sources: options[:plugin_sources],
|
||||
plugin_name: name,
|
||||
plugin_verbose: options[:verbose]
|
||||
})
|
||||
if argv.length < 1
|
||||
raise Vagrant::Errors::CLIInvalidUsage, help: opts.help.chomp if !options[:env_local]
|
||||
|
||||
errors = @env.vagrantfile.config.vagrant.validate(nil)
|
||||
if !errors["vagrant"].empty?
|
||||
raise Errors::ConfigInvalid,
|
||||
errors: Util::TemplateRenderer.render(
|
||||
"config/validation_failed",
|
||||
errors: errors)
|
||||
end
|
||||
|
||||
local_plugins = @env.vagrantfile.config.vagrant.plugins
|
||||
plugin_list = local_plugins.map do |name, info|
|
||||
"#{name} (#{info.fetch(:version, "> 0")})"
|
||||
end.join("\n")
|
||||
|
||||
|
||||
@env.ui.info(I18n.t("vagrant.plugins.local.install_all",
|
||||
plugins: plugin_list) + "\n")
|
||||
|
||||
# Pause to allow user to cancel
|
||||
sleep(LOCAL_INSTALL_PAUSE)
|
||||
|
||||
local_plugins.each do |name, info|
|
||||
action(Action.action_install,
|
||||
plugin_entry_point: info[:entry_point],
|
||||
plugin_version: info[:version],
|
||||
plugin_sources: info[:sources] || Vagrant::Bundler::DEFAULT_GEM_SOURCES.dup,
|
||||
plugin_name: name,
|
||||
plugin_env_local: true
|
||||
)
|
||||
end
|
||||
else
|
||||
# Install the gem
|
||||
argv.each do |name|
|
||||
action(Action.action_install,
|
||||
plugin_entry_point: options[:entry_point],
|
||||
plugin_version: options[:plugin_version],
|
||||
plugin_sources: options[:plugin_sources],
|
||||
plugin_name: name,
|
||||
plugin_verbose: options[:verbose],
|
||||
plugin_env_local: options[:env_local]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# Success, exit status 0
|
||||
|
|
|
@ -9,6 +9,9 @@ module VagrantPlugins
|
|||
def execute
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant plugin list [-h]"
|
||||
|
||||
# Stub option to allow Vagrantfile loading
|
||||
o.on("--local", "Include local project plugins"){|_|}
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
|
|
|
@ -7,8 +7,14 @@ module VagrantPlugins
|
|||
module Command
|
||||
class Repair < Base
|
||||
def execute
|
||||
options = {}
|
||||
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant plugin repair [-h]"
|
||||
|
||||
o.on("--local", "Repair plugins in local project") do |l|
|
||||
options[:env_local] = l
|
||||
end
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
|
@ -16,8 +22,12 @@ module VagrantPlugins
|
|||
return if !argv
|
||||
raise Vagrant::Errors::CLIInvalidUsage, help: opts.help.chomp if argv.length > 0
|
||||
|
||||
if Vagrant::Plugin::Manager.instance.local_file
|
||||
action(Action.action_repair_local, env: @env)
|
||||
end
|
||||
|
||||
# Attempt to repair installed plugins
|
||||
action(Action.action_repair)
|
||||
action(Action.action_repair, options)
|
||||
|
||||
# Success, exit status 0
|
||||
0
|
||||
|
|
|
@ -7,8 +7,13 @@ module VagrantPlugins
|
|||
module Command
|
||||
class Uninstall < Base
|
||||
def execute
|
||||
options = {}
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant plugin uninstall <name> [<name2> <name3> ...] [-h]"
|
||||
|
||||
o.on("--local", "Remove plugin from local project") do |l|
|
||||
options[:env_local] = l
|
||||
end
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
|
@ -18,7 +23,7 @@ module VagrantPlugins
|
|||
|
||||
# Uninstall the gems
|
||||
argv.each do |gem|
|
||||
action(Action.action_uninstall, plugin_name: gem)
|
||||
action(Action.action_uninstall, plugin_name: gem, env_local: options[:env_local])
|
||||
end
|
||||
|
||||
# Success, exit status 0
|
||||
|
|
|
@ -10,9 +10,14 @@ module VagrantPlugins
|
|||
include MixinInstallOpts
|
||||
|
||||
def execute
|
||||
options = {}
|
||||
opts = OptionParser.new do |o|
|
||||
o.banner = "Usage: vagrant plugin update [names...] [-h]"
|
||||
o.separator ""
|
||||
|
||||
o.on("--local", "Update plugin in local project") do |l|
|
||||
options[:env_local] = l
|
||||
end
|
||||
end
|
||||
|
||||
# Parse the options
|
||||
|
@ -22,6 +27,7 @@ module VagrantPlugins
|
|||
# Update the gem
|
||||
action(Action.action_update, {
|
||||
plugin_name: argv,
|
||||
env_local: options[:env_local]
|
||||
})
|
||||
|
||||
# Success, exit status 0
|
||||
|
|
|
@ -5,16 +5,25 @@ module VagrantPlugins
|
|||
class VagrantConfig < Vagrant.plugin("2", :config)
|
||||
attr_accessor :host
|
||||
attr_accessor :sensitive
|
||||
attr_accessor :plugins
|
||||
|
||||
VALID_PLUGIN_KEYS = [:sources, :version, :entry_point].freeze
|
||||
|
||||
def initialize
|
||||
@host = UNSET_VALUE
|
||||
@sensitive = UNSET_VALUE
|
||||
@plugins = UNSET_VALUE
|
||||
end
|
||||
|
||||
def finalize!
|
||||
@host = :detect if @host == UNSET_VALUE
|
||||
@host = @host.to_sym if @host
|
||||
@sensitive = nil if @sensitive == UNSET_VALUE
|
||||
if @plugins == UNSET_VALUE
|
||||
@plugins = {}
|
||||
else
|
||||
@plugins = format_plugins(@plugins)
|
||||
end
|
||||
|
||||
if @sensitive.is_a?(Array) || @sensitive.is_a?(String)
|
||||
Array(@sensitive).each do |value|
|
||||
|
@ -23,18 +32,48 @@ module VagrantPlugins
|
|||
end
|
||||
end
|
||||
|
||||
# Validate the configuration
|
||||
#
|
||||
# @param [Vagrant::Machine, NilClass] machine Machine instance or nil
|
||||
# @return [Hash]
|
||||
def validate(machine)
|
||||
errors = _detected_errors
|
||||
|
||||
if @sensitive && (!@sensitive.is_a?(Array) && !@sensitive.is_a?(String))
|
||||
errors << I18n.t("vagrant.config.root.sensitive_bad_type")
|
||||
end
|
||||
|
||||
@plugins.each do |plugin_name, plugin_info|
|
||||
invalid_keys = plugin_info.keys - VALID_PLUGIN_KEYS
|
||||
if !invalid_keys.empty?
|
||||
errors << I18n.t("vagrant.config.root.plugins_bad_key",
|
||||
plugin_name: plugin_name,
|
||||
plugin_key: invalid_keys.join(", ")
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
{"vagrant" => errors}
|
||||
end
|
||||
|
||||
def to_s
|
||||
"Vagrant"
|
||||
end
|
||||
|
||||
def format_plugins(val)
|
||||
result = case val
|
||||
when String
|
||||
{val => {}}
|
||||
when Array
|
||||
Hash[val.map{|item| [item.to_s, {}]}]
|
||||
else
|
||||
val
|
||||
end
|
||||
result.keys.each do |key|
|
||||
result[key] = Hash[result[key].map{|k,v| [k.to_sym, v]}]
|
||||
end
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -410,6 +410,23 @@ en:
|
|||
|
||||
Backup: %{backup_path}
|
||||
|
||||
plugins:
|
||||
local:
|
||||
uninstalled_plugins: |-
|
||||
Vagrant has detected project local plugins configured for this
|
||||
project which are not installed.
|
||||
|
||||
%{plugins}
|
||||
request_plugin_install: |-
|
||||
Install local plugins (Y/N)
|
||||
|
||||
install_all: |-
|
||||
Vagrant will now install the following plugins to the local project
|
||||
which have been defined in current Vagrantfile:
|
||||
|
||||
%{plugins}
|
||||
|
||||
Press ctrl-c to cancel...
|
||||
#-------------------------------------------------------------------------------
|
||||
# Translations for exception classes
|
||||
#-------------------------------------------------------------------------------
|
||||
|
@ -1092,7 +1109,7 @@ en:
|
|||
|
||||
%{message}
|
||||
plugin_not_installed: |-
|
||||
The plugin '%{name}' is not installed. Please install it first.
|
||||
The plugin '%{name}' is not currently installed.
|
||||
plugin_state_file_not_parsable: |-
|
||||
Failed to parse the state file "%{path}":
|
||||
%{message}
|
||||
|
@ -1117,6 +1134,20 @@ en:
|
|||
%{error_msg}
|
||||
|
||||
Source: %{source}
|
||||
plugin_no_local_error: |-
|
||||
Vagrant is not currently working within a Vagrant project directory. Local
|
||||
plugins are only supported within a Vagrant project directory.
|
||||
plugin_missing_local_error: |-
|
||||
Vagrant is missing plugins required by the currently loaded Vagrantfile.
|
||||
Please install the configured plugins and run this command again. The
|
||||
following plugins are currently missing:
|
||||
|
||||
%{plugins}
|
||||
|
||||
To install the plugins configured in the current Vagrantfile run the
|
||||
following command:
|
||||
|
||||
vagrant plugin install --local
|
||||
powershell_not_found: |-
|
||||
Failed to locate the powershell executable on the available PATH. Please
|
||||
ensure powershell is installed and available on the local PATH, then
|
||||
|
@ -1711,6 +1742,10 @@ en:
|
|||
sensitive_bad_type: |-
|
||||
Invalid type provided for `sensitive`. The sensitive option expects a string
|
||||
or an array of strings.
|
||||
plugins_bad_key: |-
|
||||
Invalid plugin configuration detected for `%{plugin_name}` plugin.
|
||||
|
||||
Unknown keys: %{plugin_key}
|
||||
bad_key: |-
|
||||
Unknown configuration section '%{key}'.
|
||||
ssh:
|
||||
|
@ -1889,9 +1924,13 @@ en:
|
|||
|
||||
%{message}
|
||||
repairing: |-
|
||||
Repairing currently installed plugins. This may take a few minutes...
|
||||
Repairing currently installed global plugins. This may take a few minutes...
|
||||
repairing_local: |-
|
||||
Repairing currently installed local project plugins. This may take a few minutes...
|
||||
repair_complete: |-
|
||||
Installed plugins successfully repaired!
|
||||
repair_local_complete: |-
|
||||
Local project plugins successfully repaired!
|
||||
repair_failed: |-
|
||||
Failed to automatically repair installed Vagrant plugins. To fix this
|
||||
problem remove all user installed plugins and reinstall. Vagrant can
|
||||
|
|
|
@ -121,7 +121,10 @@ describe "vagrant bin" do
|
|||
context "plugin commands" do
|
||||
let(:argv) { ["plugin"] }
|
||||
|
||||
before { allow(ENV).to receive(:[]=) }
|
||||
before do
|
||||
allow(ENV).to receive(:[]=)
|
||||
allow(ENV).to receive(:[])
|
||||
end
|
||||
|
||||
it "should unset vagrantfile" do
|
||||
expect(Vagrant::Environment).to receive(:new).
|
||||
|
@ -143,5 +146,23 @@ describe "vagrant bin" do
|
|||
expect(ENV).not_to receive(:[]=).with("VAGRANT_DISABLE_PLUGIN_INIT", "1")
|
||||
end
|
||||
end
|
||||
|
||||
context "--local" do
|
||||
let(:argv) { ["plugin", "install", "--local"] }
|
||||
|
||||
it "should not unset vagrantfile" do
|
||||
expect(Vagrant::Environment).to receive(:new).
|
||||
with(hash_excluding(vagrantfile_name: "")).and_return(env)
|
||||
end
|
||||
end
|
||||
|
||||
context "with VAGRANT_LOCAL_PLUGINS_LOAD enabled" do
|
||||
before { expect(ENV).to receive(:[]).with("VAGRANT_LOCAL_PLUGINS_LOAD").and_return("1") }
|
||||
|
||||
it "should not unset vagrantfile" do
|
||||
expect(Vagrant::Environment).to receive(:new).
|
||||
with(hash_excluding(vagrantfile_name: "")).and_return(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,21 +5,33 @@ describe VagrantPlugins::CommandPlugin::Action::ExpungePlugins do
|
|||
let(:home_path){ '/fake/file/path/.vagrant.d' }
|
||||
let(:gems_path){ "#{home_path}/gems" }
|
||||
let(:force){ true }
|
||||
let(:env_local){ false }
|
||||
let(:env_local_only){ nil }
|
||||
let(:global_only){ nil }
|
||||
let(:env) {{
|
||||
ui: Vagrant::UI::Silent.new,
|
||||
home_path: home_path,
|
||||
gems_path: gems_path,
|
||||
force: force
|
||||
force: force,
|
||||
env_local: env_local,
|
||||
env_local_only: env_local_only,
|
||||
global_only: global_only
|
||||
}}
|
||||
|
||||
let(:manager) { double("manager") }
|
||||
let(:user_file) { double("user_file", path: user_file_pathname) }
|
||||
let(:user_file_pathname) { double("user_file_pathname", exist?: true, delete: true) }
|
||||
let(:local_file) { nil }
|
||||
let(:bundler) { double("bundler", plugin_gem_path: plugin_gem_path,
|
||||
env_plugin_gem_path: env_plugin_gem_path) }
|
||||
let(:plugin_gem_path) { double("plugin_gem_path", exist?: true, rmtree: true) }
|
||||
let(:env_plugin_gem_path) { nil }
|
||||
|
||||
let(:manager) { double("manager", user_file: user_file, local_file: local_file) }
|
||||
|
||||
let(:expect_to_receive) do
|
||||
lambda do
|
||||
allow(File).to receive(:exist?).with(File.join(home_path, 'plugins.json')).and_return(true)
|
||||
allow(File).to receive(:directory?).with(gems_path).and_return(true)
|
||||
expect(FileUtils).to receive(:rm).with(File.join(home_path, 'plugins.json'))
|
||||
expect(FileUtils).to receive(:rm_rf).with(gems_path)
|
||||
expect(app).to receive(:call).with(env).once
|
||||
end
|
||||
end
|
||||
|
@ -28,6 +40,7 @@ describe VagrantPlugins::CommandPlugin::Action::ExpungePlugins do
|
|||
|
||||
before do
|
||||
allow(Vagrant::Plugin::Manager).to receive(:instance).and_return(manager)
|
||||
allow(Vagrant::Bundler).to receive(:instance).and_return(bundler)
|
||||
end
|
||||
|
||||
describe "#call" do
|
||||
|
@ -36,6 +49,8 @@ describe VagrantPlugins::CommandPlugin::Action::ExpungePlugins do
|
|||
end
|
||||
|
||||
it "should delete all plugins" do
|
||||
expect(user_file_pathname).to receive(:delete)
|
||||
expect(plugin_gem_path).to receive(:rmtree)
|
||||
subject.call(env)
|
||||
end
|
||||
|
||||
|
@ -60,5 +75,94 @@ describe VagrantPlugins::CommandPlugin::Action::ExpungePlugins do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when local option is set" do
|
||||
let(:env_local) { true }
|
||||
|
||||
it "should delete plugins" do
|
||||
expect(user_file_pathname).to receive(:delete)
|
||||
expect(plugin_gem_path).to receive(:rmtree)
|
||||
subject.call(env)
|
||||
end
|
||||
end
|
||||
|
||||
context "when local plugins exist" do
|
||||
let(:local_file) { double("local_file", path: local_file_pathname) }
|
||||
let(:local_file_pathname) { double("local_file_pathname", exist?: true, delete: true) }
|
||||
let(:env_plugin_gem_path) { double("env_plugin_gem_path", exist?: true, rmtree: true) }
|
||||
|
||||
it "should delete user and local plugins" do
|
||||
expect(user_file_pathname).to receive(:delete)
|
||||
expect(local_file_pathname).to receive(:delete)
|
||||
expect(plugin_gem_path).to receive(:rmtree)
|
||||
expect(env_plugin_gem_path).to receive(:rmtree)
|
||||
subject.call(env)
|
||||
end
|
||||
|
||||
context "when local option is set" do
|
||||
let(:env_local) { true }
|
||||
|
||||
it "should delete local plugins" do
|
||||
expect(local_file_pathname).to receive(:delete)
|
||||
expect(env_plugin_gem_path).to receive(:rmtree)
|
||||
subject.call(env)
|
||||
end
|
||||
|
||||
it "should delete user plugins" do
|
||||
expect(user_file_pathname).to receive(:delete)
|
||||
expect(plugin_gem_path).to receive(:rmtree)
|
||||
subject.call(env)
|
||||
end
|
||||
|
||||
context "when local only option is set" do
|
||||
let(:env_local_only) { true }
|
||||
|
||||
it "should delete local plugins" do
|
||||
expect(local_file_pathname).to receive(:delete)
|
||||
expect(env_plugin_gem_path).to receive(:rmtree)
|
||||
subject.call(env)
|
||||
end
|
||||
|
||||
it "should not delete user plugins" do
|
||||
expect(user_file_pathname).not_to receive(:delete)
|
||||
expect(plugin_gem_path).not_to receive(:rmtree)
|
||||
subject.call(env)
|
||||
end
|
||||
end
|
||||
|
||||
context "when global only option is set" do
|
||||
let(:global_only) { true }
|
||||
|
||||
it "should not delete local plugins" do
|
||||
expect(local_file_pathname).not_to receive(:delete)
|
||||
expect(env_plugin_gem_path).not_to receive(:rmtree)
|
||||
subject.call(env)
|
||||
end
|
||||
|
||||
it "should delete user plugins" do
|
||||
expect(user_file_pathname).to receive(:delete)
|
||||
expect(plugin_gem_path).to receive(:rmtree)
|
||||
subject.call(env)
|
||||
end
|
||||
end
|
||||
|
||||
context "when global and local only options are set" do
|
||||
let(:env_local_only) { true }
|
||||
let(:global_only) { true }
|
||||
|
||||
it "should delete local plugins" do
|
||||
expect(local_file_pathname).to receive(:delete)
|
||||
expect(env_plugin_gem_path).to receive(:rmtree)
|
||||
subject.call(env)
|
||||
end
|
||||
|
||||
it "should delete user plugins" do
|
||||
expect(user_file_pathname).to receive(:delete)
|
||||
expect(plugin_gem_path).to receive(:rmtree)
|
||||
subject.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,7 +18,7 @@ describe VagrantPlugins::CommandPlugin::Action::InstallGem do
|
|||
it "should install the plugin" do
|
||||
spec = Gem::Specification.new
|
||||
expect(manager).to receive(:install_plugin).with(
|
||||
"foo", version: nil, require: nil, sources: nil, verbose: false).once.and_return(spec)
|
||||
"foo", version: nil, require: nil, sources: nil, verbose: false, env_local: nil).once.and_return(spec)
|
||||
|
||||
expect(app).to receive(:call).with(env).once
|
||||
|
||||
|
@ -29,7 +29,7 @@ describe VagrantPlugins::CommandPlugin::Action::InstallGem do
|
|||
it "should specify the version if given" do
|
||||
spec = Gem::Specification.new
|
||||
expect(manager).to receive(:install_plugin).with(
|
||||
"foo", version: "bar", require: nil, sources: nil, verbose: false).once.and_return(spec)
|
||||
"foo", version: "bar", require: nil, sources: nil, verbose: false, env_local: nil).once.and_return(spec)
|
||||
|
||||
expect(app).to receive(:call).with(env).once
|
||||
|
||||
|
@ -41,7 +41,7 @@ describe VagrantPlugins::CommandPlugin::Action::InstallGem do
|
|||
it "should specify the entrypoint if given" do
|
||||
spec = Gem::Specification.new
|
||||
expect(manager).to receive(:install_plugin).with(
|
||||
"foo", version: "bar", require: "baz", sources: nil, verbose: false).once.and_return(spec)
|
||||
"foo", version: "bar", require: "baz", sources: nil, verbose: false, env_local: nil).once.and_return(spec)
|
||||
|
||||
expect(app).to receive(:call).with(env).once
|
||||
|
||||
|
@ -54,7 +54,7 @@ describe VagrantPlugins::CommandPlugin::Action::InstallGem do
|
|||
it "should specify the sources if given" do
|
||||
spec = Gem::Specification.new
|
||||
expect(manager).to receive(:install_plugin).with(
|
||||
"foo", version: nil, require: nil, sources: ["foo"], verbose: false).once.and_return(spec)
|
||||
"foo", version: nil, require: nil, sources: ["foo"], verbose: false, env_local: nil).once.and_return(spec)
|
||||
|
||||
expect(app).to receive(:call).with(env).once
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ describe VagrantPlugins::CommandPlugin::Action::UninstallPlugin do
|
|||
end
|
||||
|
||||
it "uninstalls the specified plugin" do
|
||||
expect(manager).to receive(:uninstall_plugin).with("bar").ordered
|
||||
expect(manager).to receive(:uninstall_plugin).with("bar", any_args).ordered
|
||||
expect(app).to receive(:call).ordered
|
||||
|
||||
env[:plugin_name] = "bar"
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
require "tmpdir"
|
||||
require_relative "../base"
|
||||
|
||||
require "vagrant/bundler"
|
||||
|
||||
describe Vagrant::Bundler do
|
||||
include_context "unit"
|
||||
|
||||
let(:iso_env) { isolated_environment }
|
||||
let(:env) { iso_env.create_vagrant_env }
|
||||
|
||||
before do
|
||||
@tmpdir = Dir.mktmpdir("vagrant-bundler-test")
|
||||
@vh = ENV["VAGRANT_HOME"]
|
||||
ENV["VAGRANT_HOME"] = @tmpdir
|
||||
end
|
||||
|
||||
after do
|
||||
ENV["VAGRANT_HOME"] = @vh
|
||||
FileUtils.rm_rf(@tmpdir)
|
||||
end
|
||||
|
||||
it "should isolate gem path based on Ruby version" do
|
||||
expect(subject.plugin_gem_path.to_s).to end_with(RUBY_VERSION)
|
||||
end
|
||||
|
||||
it "should not have an env_plugin_gem_path by default" do
|
||||
expect(subject.env_plugin_gem_path).to be_nil
|
||||
end
|
||||
|
||||
describe "#deinit" do
|
||||
it "should provide method for backwards compatibility" do
|
||||
subject.deinit
|
||||
end
|
||||
end
|
||||
|
||||
describe "#install" do
|
||||
let(:plugins){ {"my-plugin" => {"gem_version" => "> 0"}} }
|
||||
|
||||
it "should pass plugin information hash to internal install" do
|
||||
expect(subject).to receive(:internal_install).with(plugins, any_args)
|
||||
subject.install(plugins)
|
||||
end
|
||||
|
||||
it "should not include any update plugins" do
|
||||
expect(subject).to receive(:internal_install).with(anything, nil, any_args)
|
||||
subject.install(plugins)
|
||||
end
|
||||
|
||||
it "should flag local when local is true" do
|
||||
expect(subject).to receive(:internal_install).with(any_args, env_local: true)
|
||||
subject.install(plugins, true)
|
||||
end
|
||||
|
||||
it "should not flag local when local is not set" do
|
||||
expect(subject).to receive(:internal_install).with(any_args, env_local: false)
|
||||
subject.install(plugins)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#install_local" do
|
||||
let(:plugin_source){ double("plugin_source", spec: plugin_spec) }
|
||||
let(:plugin_spec){ double("plugin_spec", name: plugin_name, version: plugin_version) }
|
||||
let(:plugin_name){ "PLUGIN_NAME" }
|
||||
let(:plugin_version){ "1.0.0" }
|
||||
let(:plugin_path){ "PLUGIN_PATH" }
|
||||
let(:sources){ "SOURCES" }
|
||||
|
||||
before do
|
||||
allow(Gem::Source::SpecificFile).to receive(:new).and_return(plugin_source)
|
||||
allow(subject).to receive(:internal_install)
|
||||
end
|
||||
|
||||
it "should return plugin gem specification" do
|
||||
expect(subject.install_local(plugin_path)).to eq(plugin_spec)
|
||||
end
|
||||
|
||||
it "should set custom sources" do
|
||||
expect(subject).to receive(:internal_install) do |info, update, opts|
|
||||
expect(info[plugin_name]["sources"]).to eq(sources)
|
||||
end
|
||||
subject.install_local(plugin_path, sources: sources)
|
||||
end
|
||||
|
||||
it "should not set the update parameter" do
|
||||
expect(subject).to receive(:internal_install) do |info, update, opts|
|
||||
expect(update).to be_nil
|
||||
end
|
||||
subject.install_local(plugin_path)
|
||||
end
|
||||
|
||||
it "should not set plugin as environment local by default" do
|
||||
expect(subject).to receive(:internal_install) do |info, update, opts|
|
||||
expect(opts[:env_local]).to be_falsey
|
||||
end
|
||||
subject.install_local(plugin_path)
|
||||
end
|
||||
|
||||
it "should set if plugin is environment local" do
|
||||
expect(subject).to receive(:internal_install) do |info, update, opts|
|
||||
expect(opts[:env_local]).to be_truthy
|
||||
end
|
||||
subject.install_local(plugin_path, env_local: true)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#update" do
|
||||
let(:plugins){ :plugins }
|
||||
let(:specific){ [] }
|
||||
|
||||
after{ subject.update(plugins, specific) }
|
||||
|
||||
it "should mark update as true" do
|
||||
expect(subject).to receive(:internal_install) do |info, update, opts|
|
||||
expect(update).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
context "with specific plugins named" do
|
||||
let(:specific){ ["PLUGIN_NAME"] }
|
||||
|
||||
it "should set update to specific names" do
|
||||
expect(subject).to receive(:internal_install) do |info, update, opts|
|
||||
expect(update[:gems]).to eq(specific)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -398,7 +398,13 @@ describe Vagrant::Machine do
|
|||
callable = lambda { |_env| }
|
||||
|
||||
allow(provider).to receive(:action).with(action_name).and_return(callable)
|
||||
allow(Vagrant::Plugin::Manager.instance).to receive(:installed_plugins)
|
||||
|
||||
# The first call here is to allow the environment to setup with attempting
|
||||
# to load a plugin that does not exist
|
||||
expect(Vagrant::Plugin::Manager.instance).to receive(:installed_plugins)
|
||||
.and_return({})
|
||||
|
||||
expect(Vagrant::Plugin::Manager.instance).to receive(:installed_plugins)
|
||||
.and_return({"vagrant-triggers"=>"stuff"})
|
||||
|
||||
expect(instance.instance_variable_get(:@triggers)).not_to receive(:fire_triggers)
|
||||
|
|
|
@ -26,13 +26,98 @@ describe Vagrant::Plugin::Manager do
|
|||
|
||||
subject { described_class.new(path) }
|
||||
|
||||
describe "#globalize!" do
|
||||
let(:plugins) { double("plugins") }
|
||||
|
||||
before do
|
||||
allow(subject).to receive(:bundler_init)
|
||||
allow(subject).to receive(:installed_plugins).and_return(plugins)
|
||||
end
|
||||
|
||||
it "should init bundler with installed plugins" do
|
||||
expect(subject).to receive(:bundler_init).with(plugins)
|
||||
subject.globalize!
|
||||
end
|
||||
|
||||
it "should return installed plugins" do
|
||||
expect(subject.globalize!).to eq(plugins)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#localize!" do
|
||||
let(:env) { double("env", local_data_path: local_data_path) }
|
||||
let(:local_data_path) { double("local_data_path") }
|
||||
let(:plugins) { double("plugins") }
|
||||
let(:state_file) { double("state_file", installed_plugins: plugins) }
|
||||
|
||||
before do
|
||||
allow(Vagrant::Plugin::StateFile).to receive(:new).and_return(state_file)
|
||||
allow(bundler).to receive(:environment_path=)
|
||||
allow(local_data_path).to receive(:join).and_return(local_data_path)
|
||||
allow(subject).to receive(:bundler_init)
|
||||
end
|
||||
|
||||
context "without local data path defined" do
|
||||
let(:local_data_path) { nil }
|
||||
|
||||
it "should not do any initialization" do
|
||||
expect(subject).not_to receive(:bundler_init)
|
||||
subject.localize!(env)
|
||||
end
|
||||
|
||||
it "should return nil" do
|
||||
expect(subject.localize!(env)).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
it "should run bundler initialization" do
|
||||
expect(subject).to receive(:bundler_init).with(plugins)
|
||||
subject.localize!(env)
|
||||
end
|
||||
|
||||
it "should return plugins" do
|
||||
expect(subject.localize!(env)).to eq(plugins)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#bundler_init" do
|
||||
let(:plugins) { {"plugin_name" => {}} }
|
||||
|
||||
before do
|
||||
allow(Vagrant).to receive(:plugins_init?).and_return(true)
|
||||
allow(bundler).to receive(:init!)
|
||||
end
|
||||
|
||||
it "should init the bundler instance with plugins" do
|
||||
expect(bundler).to receive(:init!).with(plugins)
|
||||
subject.bundler_init(plugins)
|
||||
end
|
||||
|
||||
it "should return nil" do
|
||||
expect(subject.bundler_init(plugins)).to be_nil
|
||||
end
|
||||
|
||||
context "with plugin init disabled" do
|
||||
before { expect(Vagrant).to receive(:plugins_init?).and_return(false) }
|
||||
|
||||
it "should return nil" do
|
||||
expect(subject.bundler_init(plugins)).to be_nil
|
||||
end
|
||||
|
||||
it "should not init the bundler instance" do
|
||||
expect(bundler).not_to receive(:init!).with(plugins)
|
||||
subject.bundler_init(plugins)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#install_plugin" do
|
||||
it "installs the plugin and adds it to the state file" do
|
||||
specs = Array.new(5) { Gem::Specification.new }
|
||||
specs[3].name = "foo"
|
||||
expect(bundler).to receive(:install).once.with(any_args) { |plugins, local|
|
||||
expect(plugins).to have_key("foo")
|
||||
expect(local).to be(false)
|
||||
expect(local).to be_falsey
|
||||
}.and_return(specs)
|
||||
expect(bundler).to receive(:clean)
|
||||
|
||||
|
@ -95,7 +180,7 @@ describe Vagrant::Plugin::Manager do
|
|||
expect(bundler).to receive(:install).once.with(any_args) { |plugins, local|
|
||||
expect(plugins).to have_key("foo")
|
||||
expect(plugins["foo"]["gem_version"]).to eql(">= 0.1.0")
|
||||
expect(local).to be(false)
|
||||
expect(local).to be_falsey
|
||||
}.and_return(specs)
|
||||
expect(bundler).to receive(:clean)
|
||||
|
||||
|
@ -110,7 +195,7 @@ describe Vagrant::Plugin::Manager do
|
|||
expect(bundler).to receive(:install).once.with(any_args) { |plugins, local|
|
||||
expect(plugins).to have_key("foo")
|
||||
expect(plugins["foo"]["gem_version"]).to eql("0.1.0")
|
||||
expect(local).to be(false)
|
||||
expect(local).to be_falsey
|
||||
}.and_return(specs)
|
||||
expect(bundler).to receive(:clean)
|
||||
|
||||
|
@ -140,6 +225,8 @@ describe Vagrant::Plugin::Manager do
|
|||
end
|
||||
|
||||
it "masks bundler errors with our own error" do
|
||||
sf = Vagrant::Plugin::StateFile.new(path)
|
||||
sf.add_plugin("foo")
|
||||
expect(bundler).to receive(:clean).and_raise(Gem::InstallError)
|
||||
|
||||
expect { subject.uninstall_plugin("foo") }.
|
||||
|
|
|
@ -32,6 +32,7 @@ describe Vagrant::Plugin::StateFile do
|
|||
"require" => "",
|
||||
"sources" => [],
|
||||
"installed_gem_version" => nil,
|
||||
"env_local" => false,
|
||||
})
|
||||
end
|
||||
|
||||
|
|
|
@ -45,6 +45,9 @@ $ vagrant plugin expunge --reinstall
|
|||
This command accepts optional command-line flags:
|
||||
|
||||
* `--force` - Do not prompt for confirmation prior to removal
|
||||
* `--global-only` - Only expunge global plugins
|
||||
* `--local` - Include plugins in local project
|
||||
* `--local-only` - Only expunge local project plugins
|
||||
* `--reinstall` - Attempt to reinstall plugins after removal
|
||||
|
||||
# Plugin Install
|
||||
|
@ -79,6 +82,8 @@ This command accepts optional command-line flags:
|
|||
Most of the time, this is correct. If the plugin you are installing has
|
||||
another entrypoint, this flag can be used to specify it.
|
||||
|
||||
* `--local` - Install plugin to the local Vagrant project only.
|
||||
|
||||
* `--plugin-clean-sources` - Clears all sources that have been defined so
|
||||
far. This is an advanced feature. The use case is primarily for corporate
|
||||
firewalls that prevent access to RubyGems.org.
|
||||
|
@ -111,6 +116,10 @@ If a version constraint was specified for a plugin when installing it, the
|
|||
constraint will be listed as well. Other plugin-specific information may
|
||||
be shown, too.
|
||||
|
||||
This command accepts optional command-line flags:
|
||||
|
||||
* `--local` - Include local project plugins.
|
||||
|
||||
# Plugin Repair
|
||||
|
||||
Vagrant may fail to properly initialize user installed custom plugins. This can
|
||||
|
@ -121,6 +130,10 @@ to automatically repair the problem.
|
|||
If automatic repair is not successful, refer to the [expunge](#plugin-expunge)
|
||||
command
|
||||
|
||||
This command accepts optional command-line flags:
|
||||
|
||||
* `--local` - Repair local project plugins.
|
||||
|
||||
# Plugin Uninstall
|
||||
|
||||
**Command: `vagrant plugin uninstall <name> [<name2> <name3> ...]`**
|
||||
|
@ -130,6 +143,10 @@ plugin will also be uninstalled assuming no other plugin needs them.
|
|||
|
||||
If multiple plugins are given, multiple plugins will be uninstalled.
|
||||
|
||||
This command accepts optional command-line flags:
|
||||
|
||||
* `--local` - Uninstall plugin from local project.
|
||||
|
||||
# Plugin Update
|
||||
|
||||
**Command: `vagrant plugin update [<name>]`**
|
||||
|
@ -142,3 +159,7 @@ the plugin using `vagrant plugin install`.
|
|||
If a name is specified, only that single plugin will be updated. If a
|
||||
name is specified of a plugin that is not installed, this command will not
|
||||
install it.
|
||||
|
||||
This command accepts optional command-line flags:
|
||||
|
||||
* `--local` - Update plugin from local project.
|
||||
|
|
|
@ -161,6 +161,19 @@ may be desirable to ignore inaccessible sources and continue with the
|
|||
plugin installation. Enabling this value will cause Vagrant to simply log
|
||||
the plugin source error and continue.
|
||||
|
||||
## `VAGRANT_INSTALL_LOCAL_PLUGINS`
|
||||
|
||||
If this is set to any value, Vagrant will not prompt for confirmation
|
||||
prior to installing local plugins which have been defined within the
|
||||
local Vagrantfile.
|
||||
|
||||
## `VAGRANT_LOCAL_PLUGINS_LOAD`
|
||||
|
||||
If this is set Vagrant will not stub the Vagrantfile when running
|
||||
`vagrant plugin` commands. When this environment variable is set the
|
||||
`--local` flag will not be required by `vagrant plugin` commands to
|
||||
enable local project plugins.
|
||||
|
||||
## `VAGRANT_NO_PARALLEL`
|
||||
|
||||
If this is set, Vagrant will not perform any parallel operations (such as
|
||||
|
|
|
@ -22,6 +22,38 @@ the host. Vagrant needs to know this information in order to perform some
|
|||
host-specific things, such as preparing NFS folders if they're enabled.
|
||||
You should only manually set this if auto-detection fails.
|
||||
|
||||
`config.vagrant.plugins` - (string, array, hash) - Define plugin, list of
|
||||
plugins, or definition of plugins to install for the local project. Vagrant
|
||||
will require these plugins be installed and available for the project. If
|
||||
the plugins are not available, it will attempt to automatically install
|
||||
them into the local project. When requiring a single plugin, a string can
|
||||
be provided:
|
||||
|
||||
```ruby
|
||||
config.vagrant.plugins = "vagrant-plugin"
|
||||
```
|
||||
|
||||
If multiple plugins are required, they can be provided as an array:
|
||||
|
||||
```ruby
|
||||
config.vagrant.plugins = ["vagrant-plugin", "vagrant-other-plugin"]
|
||||
```
|
||||
|
||||
Plugins can also be defined as a Hash, which supports setting extra options
|
||||
for the plugins. When a Hash is used, the key is the name of the plugin, and
|
||||
the value is a Hash of options for the plugin. For example, to set an explicit
|
||||
version of a plugin to install:
|
||||
|
||||
```ruby
|
||||
config.vagrant.plugins = {"vagrant-scp" => {"version" => "1.0.0"}}
|
||||
```
|
||||
|
||||
Supported options are:
|
||||
|
||||
* `entry_point` - Path for Vagrant to load plugin
|
||||
* `sources` - Custom sources for downloading plugin
|
||||
* `version` - Version constraint for plugin
|
||||
|
||||
`config.vagrant.sensitive` - (string, array) - Value or list of values that
|
||||
should not be displayed in Vagrant's output. Value(s) will be removed from
|
||||
Vagrant's normal UI output as well as logger output.
|
||||
|
|
Loading…
Reference in New Issue