From ac1404b9acd835a03264b16877652cc01e94eef8 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 2 Sep 2013 09:31:26 -0700 Subject: [PATCH] commands/plugin: Add "update" subcommand --- CHANGELOG.md | 1 + lib/vagrant/errors.rb | 4 ++ plugins/commands/plugin/action.rb | 11 +++++ .../plugin/action/plugin_exists_check.rb | 26 ++++++++++++ plugins/commands/plugin/command/install.rb | 25 ++--------- .../plugin/command/mixin_install_opts.rb | 30 ++++++++++++++ plugins/commands/plugin/command/root.rb | 5 +++ plugins/commands/plugin/command/update.rb | 41 +++++++++++++++++++ templates/locales/en.yml | 2 + 9 files changed, 124 insertions(+), 21 deletions(-) create mode 100644 plugins/commands/plugin/action/plugin_exists_check.rb create mode 100644 plugins/commands/plugin/command/mixin_install_opts.rb create mode 100644 plugins/commands/plugin/command/update.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 13b8c0ca6..0788804d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ BACKWARDS INCOMPATIBILITY: FEATURES: + - New command: `vagrant plugin update` to update specific installed plugins. - Salt provisioner. [GH-1626] - Mac OS X guest support. [GH-1914] - CoreOS guest support. Change host names and configure networks on diff --git a/lib/vagrant/errors.rb b/lib/vagrant/errors.rb index 791e2bcc4..4633e8216 100644 --- a/lib/vagrant/errors.rb +++ b/lib/vagrant/errors.rb @@ -411,6 +411,10 @@ module Vagrant error_key(:plugin_not_found) end + class PluginNotInstalled < VagrantError + error_key(:plugin_not_installed) + end + class SCPPermissionDenied < VagrantError error_key(:scp_permission_denied) end diff --git a/plugins/commands/plugin/action.rb b/plugins/commands/plugin/action.rb index 414833e89..a132aec13 100644 --- a/plugins/commands/plugin/action.rb +++ b/plugins/commands/plugin/action.rb @@ -39,12 +39,23 @@ module VagrantPlugins end end + # This middleware sequence will update a plugin. + def self.action_update + Vagrant::Action::Builder.new.tap do |b| + b.use BundlerCheck + b.use PluginExistsCheck + b.use InstallGem + b.use PruneGems + end + end + # The autoload farm action_root = Pathname.new(File.expand_path("../action", __FILE__)) autoload :BundlerCheck, action_root.join("bundler_check") autoload :InstallGem, action_root.join("install_gem") autoload :LicensePlugin, action_root.join("license_plugin") autoload :ListPlugins, action_root.join("list_plugins") + autoload :PluginExistsCheck, action_root.join("plugin_exists_check") autoload :PruneGems, action_root.join("prune_gems") autoload :UninstallPlugin, action_root.join("uninstall_plugin") end diff --git a/plugins/commands/plugin/action/plugin_exists_check.rb b/plugins/commands/plugin/action/plugin_exists_check.rb new file mode 100644 index 000000000..c56bd9c14 --- /dev/null +++ b/plugins/commands/plugin/action/plugin_exists_check.rb @@ -0,0 +1,26 @@ +require "set" + +module VagrantPlugins + module CommandPlugin + module Action + # This class checks to see if the plugin is installed already, and + # if so, raises an exception/error to output to the user. + class PluginExistsCheck + def initialize(app, env) + @app = app + end + + def call(env) + # Get the list of installed plugins according to the state file + installed = Set.new(env[:plugin_state_file].installed_plugins) + if !installed.include?(env[:plugin_name]) + raise Vagrant::Errors::PluginNotInstalled, + name: env[:plugin_name] + end + + @app.call(env) + end + end + end + end +end diff --git a/plugins/commands/plugin/command/install.rb b/plugins/commands/plugin/command/install.rb index b240e2aa9..6667fd062 100644 --- a/plugins/commands/plugin/command/install.rb +++ b/plugins/commands/plugin/command/install.rb @@ -1,38 +1,21 @@ require 'optparse' require_relative "base" +require_relative "mixin_install_opts" module VagrantPlugins module CommandPlugin module Command class Install < Base + include MixinInstallOpts + def execute options = {} opts = OptionParser.new do |o| o.banner = "Usage: vagrant plugin install [-h]" o.separator "" - - o.on("--entry-point NAME", String, - "The name of the entry point file for loading the plugin.") do |entry_point| - options[:entry_point] = entry_point - end - - o.on("--plugin-prerelease", - "Allow prerelease versions of this plugin.") do |plugin_prerelease| - options[:plugin_prerelease] = plugin_prerelease - end - - o.on("--plugin-source PLUGIN_SOURCE", String, - "Add a RubyGems repository source") do |plugin_source| - options[:plugin_sources] ||= [] - options[:plugin_sources] << plugin_source - end - - o.on("--plugin-version PLUGIN_VERSION", String, - "Install a specific version of the plugin") do |plugin_version| - options[:plugin_version] = plugin_version - end + build_install_opts(o, options) end # Parse the options diff --git a/plugins/commands/plugin/command/mixin_install_opts.rb b/plugins/commands/plugin/command/mixin_install_opts.rb new file mode 100644 index 000000000..96c879968 --- /dev/null +++ b/plugins/commands/plugin/command/mixin_install_opts.rb @@ -0,0 +1,30 @@ +module VagrantPlugins + module CommandPlugin + module Command + module MixinInstallOpts + def build_install_opts(o, options) + o.on("--entry-point NAME", String, + "The name of the entry point file for loading the plugin.") do |entry_point| + options[:entry_point] = entry_point + end + + o.on("--plugin-prerelease", + "Allow prerelease versions of this plugin.") do |plugin_prerelease| + options[:plugin_prerelease] = plugin_prerelease + end + + o.on("--plugin-source PLUGIN_SOURCE", String, + "Add a RubyGems repository source") do |plugin_source| + options[:plugin_sources] ||= [] + options[:plugin_sources] << plugin_source + end + + o.on("--plugin-version PLUGIN_VERSION", String, + "Install a specific version of the plugin") do |plugin_version| + options[:plugin_version] = plugin_version + end + end + end + end + end +end diff --git a/plugins/commands/plugin/command/root.rb b/plugins/commands/plugin/command/root.rb index 18e4749de..1bef44894 100644 --- a/plugins/commands/plugin/command/root.rb +++ b/plugins/commands/plugin/command/root.rb @@ -25,6 +25,11 @@ module VagrantPlugins List end + @subcommands.register(:update) do + require_relative "update" + Update + end + @subcommands.register(:uninstall) do require_relative "uninstall" Uninstall diff --git a/plugins/commands/plugin/command/update.rb b/plugins/commands/plugin/command/update.rb new file mode 100644 index 000000000..ca4bbb746 --- /dev/null +++ b/plugins/commands/plugin/command/update.rb @@ -0,0 +1,41 @@ +require 'optparse' + +require_relative "base" +require_relative "mixin_install_opts" + +module VagrantPlugins + module CommandPlugin + module Command + class Update < Base + include MixinInstallOpts + + def execute + options = {} + + opts = OptionParser.new do |o| + o.banner = "Usage: vagrant plugin update [-h]" + o.separator "" + build_install_opts(o, options) + end + + # Parse the options + argv = parse_options(opts) + return if !argv + raise Vagrant::Errors::CLIInvalidUsage, :help => opts.help.chomp if argv.length < 1 + + # Update the gem + action(Action.action_update, { + :plugin_entry_point => options[:entry_point], + :plugin_prerelease => options[:plugin_prerelease], + :plugin_version => options[:plugin_version], + :plugin_sources => options[:plugin_sources], + :plugin_name => argv[0] + }) + + # Success, exit status 0 + 0 + end + end + end + end +end diff --git a/templates/locales/en.yml b/templates/locales/en.yml index 961b9d3e9..e02e6622d 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -417,6 +417,8 @@ en: plugin_not_found: |- The plugin '%{name}' could not be found. Please install this plugin prior to attempting to do anything with it. + plugin_not_installed: |- + The plugin '%{name}' is not installed. Please install it first. port_collision_resume: |- This VM cannot be resumed, because the forwarded ports would collide with a running program (it could be another virtual machine). Normally,