Introduce `type` and `command` triggers
This commit introduces some basic functionality for typed triggers: - command - action Command triggers are triggers that will run before or after a given sub-command. Action triggers are for running triggers before or after internal actions for Vagrant. This could be before or after a provision step, before or after synced folders, or networking, etc.
This commit is contained in:
parent
87214ed840
commit
fefb702359
|
@ -0,0 +1,23 @@
|
|||
module Vagrant
|
||||
module Action
|
||||
module Builtin
|
||||
# After Trigger
|
||||
class AfterTriggerAction
|
||||
# @param [Symbol] action_name - The action class name to fire on
|
||||
def initialize(app, env, action_name, triggers)
|
||||
@app = app
|
||||
@env = env
|
||||
@triggers = triggers
|
||||
@action_name = action_name
|
||||
end
|
||||
|
||||
def call(env)
|
||||
@triggers.fire_triggers(@action_name, :after, nil, :action) if Vagrant::Util::Experimental.feature_enabled?("typed_triggers");
|
||||
|
||||
# Carry on
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,22 @@
|
|||
module Vagrant
|
||||
module Action
|
||||
module Builtin
|
||||
# Before trigger
|
||||
class BeforeTriggerAction
|
||||
def initialize(app, env, action_name, triggers)
|
||||
@app = app
|
||||
@env = env
|
||||
@triggers = triggers
|
||||
@action_name = action_name
|
||||
end
|
||||
|
||||
def call(env)
|
||||
@triggers.fire_triggers(@action_name, :before, nil, :action) if Vagrant::Util::Experimental.feature_enabled?("typed_triggers");
|
||||
|
||||
# Carry on
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,6 +2,7 @@ require 'log4r'
|
|||
|
||||
require 'vagrant/action/hook'
|
||||
require 'vagrant/util/busy'
|
||||
require 'vagrant/util/experimental'
|
||||
|
||||
module Vagrant
|
||||
module Action
|
||||
|
@ -33,6 +34,16 @@ module Vagrant
|
|||
environment.merge!(@lazy_globals.call) if @lazy_globals
|
||||
environment.merge!(options || {})
|
||||
|
||||
if Vagrant::Util::Experimental.feature_enabled?("typed_triggers")
|
||||
# NOTE: Triggers are initialized later in the Action::Runer because of
|
||||
# how `@lazy_globals` are evaluated. Rather than trying to guess where
|
||||
# the `env` is coming from, we can wait until they're merged into a single
|
||||
# hash above.
|
||||
env = environment[:env]
|
||||
ui = Vagrant::UI::Prefixed.new(env.ui, "vargant")
|
||||
triggers = Vagrant::Plugin::V2::Trigger.new(env, env.vagrantfile.config.trigger, nil, ui)
|
||||
end
|
||||
|
||||
# Setup the action hooks
|
||||
hooks = Vagrant.plugin("2").manager.action_hooks(environment[:action_name])
|
||||
if !hooks.empty?
|
||||
|
@ -61,10 +72,15 @@ module Vagrant
|
|||
@@reported_interrupt = true
|
||||
end
|
||||
|
||||
action_name = environment[:action_name]
|
||||
triggers.fire_triggers(action_name, :before, nil, :action) if Vagrant::Util::Experimental.feature_enabled?("typed_triggers")
|
||||
|
||||
# We place a process lock around every action that is called
|
||||
@logger.info("Running action: #{environment[:action_name]} #{callable_id}")
|
||||
Util::Busy.busy(int_callback) { callable.call(environment) }
|
||||
|
||||
triggers.fire_triggers(action_name, :after, nil, :action) if Vagrant::Util::Experimental.feature_enabled?("typed_triggers")
|
||||
|
||||
# Return the environment in case there are things in there that
|
||||
# the caller wants to use.
|
||||
environment
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
require "log4r"
|
||||
require 'vagrant/util/experimental'
|
||||
require 'vagrant/action/builtin/before_trigger'
|
||||
require 'vagrant/action/builtin/after_trigger'
|
||||
|
||||
module Vagrant
|
||||
module Action
|
||||
|
@ -16,8 +19,19 @@ module Vagrant
|
|||
attr_accessor :actions, :stack
|
||||
|
||||
def initialize(actions, env)
|
||||
if Vagrant::Util::Experimental.feature_enabled?("typed_triggers")
|
||||
if env[:trigger_env]
|
||||
@env = env[:trigger_env]
|
||||
else
|
||||
@env = env[:env]
|
||||
end
|
||||
|
||||
ui = Vagrant::UI::Prefixed.new(@env.ui, "vargant")
|
||||
@triggers = Vagrant::Plugin::V2::Trigger.new(@env, @env.vagrantfile.config.trigger, nil, ui)
|
||||
end
|
||||
|
||||
@stack = []
|
||||
@actions = actions.map { |m| finalize_action(m, env) }
|
||||
@actions = actions.map { |m| finalize_action(m, env) }.flatten
|
||||
@logger = Log4r::Logger.new("vagrant::action::warden")
|
||||
@last_error = nil
|
||||
end
|
||||
|
@ -87,7 +101,28 @@ module Vagrant
|
|||
if klass.is_a?(Class)
|
||||
# A action klass which is to be instantiated with the
|
||||
# app, env, and any arguments given
|
||||
klass.new(self, env, *args, &block)
|
||||
|
||||
# TODO: This wraps EVERY action in a proc, which means the recover method
|
||||
# is never called EVER.
|
||||
#
|
||||
# Maybe instead of a lambda, make a new Action class for triggers, where
|
||||
# the class has a "namespace" param so it knows when to properly
|
||||
# fire before or after the action it is wrapped around
|
||||
#
|
||||
#lambda { |e|
|
||||
# @triggers.fire_triggers(klass.name.to_sym, :before, nil, :action) if Vagrant::Util::Experimental.feature_enabled?("typed_triggers");
|
||||
# klass.new(self, env, *args, &block).call(e);
|
||||
# @triggers.fire_triggers(klass.name.to_sym, :after, nil, :action) if Vagrant::Util::Experimental.feature_enabled?("typed_triggers")
|
||||
#}
|
||||
klass_name = klass.class.name.to_sym
|
||||
[Vagrant::Action::Builtin::BeforeTriggerAction.new(self, env,
|
||||
klass_name,
|
||||
@triggers),
|
||||
klass.new(self, env, *args, &block),
|
||||
Vagrant::Action::Builtin::AfterTriggerAction.new(self, env,
|
||||
klass_name,
|
||||
@triggers)]
|
||||
#klass.new(self, env, *args, &block)
|
||||
elsif klass.respond_to?(:call)
|
||||
# Make it a lambda which calls the item then forwards
|
||||
# up the chain
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
require 'log4r'
|
||||
require 'optparse'
|
||||
|
||||
require 'vagrant/util/experimental'
|
||||
|
||||
module Vagrant
|
||||
# Manages the command line interface to Vagrant.
|
||||
class CLI < Vagrant.plugin("2", :command)
|
||||
|
@ -11,6 +13,11 @@ module Vagrant
|
|||
@logger = Log4r::Logger.new("vagrant::cli")
|
||||
@main_args, @sub_command, @sub_args = split_main_and_subcommand(argv)
|
||||
|
||||
if Vagrant::Util::Experimental.feature_enabled?("typed_triggers")
|
||||
ui = Vagrant::UI::Prefixed.new(env.ui, "vargant")
|
||||
@triggers = Vagrant::Plugin::V2::Trigger.new(env, env.vagrantfile.config.trigger, nil, ui)
|
||||
end
|
||||
|
||||
Util::CheckpointClient.instance.setup(env).check
|
||||
@logger.info("CLI: #{@main_args.inspect} #{@sub_command.inspect} #{@sub_args.inspect}")
|
||||
end
|
||||
|
@ -55,7 +62,9 @@ module Vagrant
|
|||
# Initialize and execute the command class, returning the exit status.
|
||||
result = 0
|
||||
begin
|
||||
@triggers.fire_triggers(@sub_command.to_sym, :before, nil, :command) if Vagrant::Util::Experimental.feature_enabled?("typed_triggers")
|
||||
result = command_class.new(@sub_args, @env).execute
|
||||
@triggers.fire_triggers(@sub_command.to_sym, :after, nil, :command) if Vagrant::Util::Experimental.feature_enabled?("typed_triggers")
|
||||
rescue Interrupt
|
||||
@env.ui.info(I18n.t("vagrant.cli_interrupt"))
|
||||
result = 1
|
||||
|
|
|
@ -210,7 +210,8 @@ module Vagrant
|
|||
home_path: home_path,
|
||||
root_path: root_path,
|
||||
tmp_path: tmp_path,
|
||||
ui: @ui
|
||||
ui: @ui,
|
||||
env: self
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -110,7 +110,7 @@ module Vagrant
|
|||
@ui = Vagrant::UI::Prefixed.new(@env.ui, @name)
|
||||
@ui_mutex = Mutex.new
|
||||
@state_mutex = Mutex.new
|
||||
@triggers = Vagrant::Plugin::V2::Trigger.new(@env, @config.trigger, self)
|
||||
@triggers = Vagrant::Plugin::V2::Trigger.new(@env, @config.trigger, self, @ui)
|
||||
|
||||
# Read the ID, which is usually in local storage
|
||||
@id = nil
|
||||
|
@ -160,10 +160,7 @@ module Vagrant
|
|||
# as extra data set on the environment hash for the middleware
|
||||
# runner.
|
||||
def action(name, opts=nil)
|
||||
plugins = Vagrant::Plugin::Manager.instance.installed_plugins
|
||||
if !plugins.keys.include?("vagrant-triggers")
|
||||
@triggers.fire_triggers(name, :before, @name.to_s)
|
||||
end
|
||||
@triggers.fire_triggers(name, :before, @name.to_s, :action)
|
||||
|
||||
@logger.info("Calling action: #{name} on provider #{@provider}")
|
||||
|
||||
|
@ -175,6 +172,10 @@ module Vagrant
|
|||
|
||||
# Extra env keys are the remaining opts
|
||||
extra_env = opts.dup
|
||||
# An environment is required for triggers to function properly. This is
|
||||
# passed in specifically for the `#Action::Warden` class triggers. We call it
|
||||
# `:trigger_env` instead of `env` in case it collides with an existing environment
|
||||
extra_env[:trigger_env] = @env
|
||||
|
||||
check_cwd # Warns the UI if the machine was last used on a different dir
|
||||
|
||||
|
@ -210,9 +211,7 @@ module Vagrant
|
|||
action_result
|
||||
end
|
||||
|
||||
if !plugins.keys.include?("vagrant-triggers")
|
||||
@triggers.fire_triggers(name, :after, @name.to_s)
|
||||
end
|
||||
@triggers.fire_triggers(name, :after, @name.to_s, :action)
|
||||
# preserve returning environment after machine action runs
|
||||
return return_env
|
||||
rescue Errors::EnvironmentLockedError
|
||||
|
|
|
@ -20,20 +20,28 @@ module Vagrant
|
|||
# @param [Vagrant::Environment] env Vagrant environment
|
||||
# @param [Kernel_V2::TriggerConfig] config Trigger configuration
|
||||
# @param [Vagrant::Machine] machine Active Machine
|
||||
def initialize(env, config, machine)
|
||||
# @param [Vagrant::UI] ui Class for printing messages to user
|
||||
def initialize(env, config, machine, ui)
|
||||
@env = env
|
||||
@config = config
|
||||
@machine = machine
|
||||
@ui = ui
|
||||
|
||||
@logger = Log4r::Logger.new("vagrant::trigger::#{self.class.to_s.downcase}")
|
||||
end
|
||||
|
||||
# Fires all triggers, if any are defined for the action and guest
|
||||
# Fires all triggers, if any are defined for the action and guest. Returns early
|
||||
# and logs a warning if the community plugin `vagrant-triggers` is installed
|
||||
#
|
||||
# @param [Symbol] action Vagrant command to fire trigger on
|
||||
# @param [Symbol] stage :before or :after
|
||||
# @param [String] guest_name The guest that invoked firing the triggers
|
||||
def fire_triggers(action, stage, guest_name)
|
||||
def fire_triggers(action, stage, guest_name, type)
|
||||
if community_plugin_detected?
|
||||
@logger.warn("Community plugin `vagrant-triggers detected, so core triggers will not fire")
|
||||
return
|
||||
end
|
||||
|
||||
# get all triggers matching action
|
||||
triggers = []
|
||||
if stage == :before
|
||||
|
@ -51,27 +59,41 @@ module Vagrant
|
|||
guest_name: guest_name
|
||||
end
|
||||
|
||||
triggers = filter_triggers(triggers, guest_name)
|
||||
triggers = filter_triggers(triggers, guest_name, type)
|
||||
|
||||
if !triggers.empty?
|
||||
@logger.info("Firing trigger for action #{action} on guest #{guest_name}")
|
||||
@machine.ui.info(I18n.t("vagrant.trigger.start", stage: stage, action: action))
|
||||
@ui.info(I18n.t("vagrant.trigger.start", type: type, stage: stage, action: action))
|
||||
fire(triggers, guest_name)
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# Internal methods, don't call these.
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
# Looks up if the community plugin `vagrant-triggers` is installed
|
||||
# and also caches the result
|
||||
#
|
||||
# @return [Boolean]
|
||||
def community_plugin_detected?
|
||||
if !defined?(@_triggers_enabled)
|
||||
plugins = Vagrant::Plugin::Manager.instance.installed_plugins
|
||||
@_triggers_enabled = plugins.keys.include?("vagrant-triggers")
|
||||
end
|
||||
@_triggers_enabled
|
||||
end
|
||||
|
||||
# Filters triggers to be fired based on configured restraints
|
||||
#
|
||||
# @param [Array] triggers An array of triggers to be filtered
|
||||
# @param [String] guest_name The name of the current guest
|
||||
# @param [Symbol] type The type of trigger (:command or :type)
|
||||
# @return [Array] The filtered array of triggers
|
||||
def filter_triggers(triggers, guest_name)
|
||||
def filter_triggers(triggers, guest_name, type)
|
||||
# look for only_on trigger constraint and if it doesn't match guest
|
||||
# name, throw it away also be sure to preserve order
|
||||
filter = triggers.dup
|
||||
|
@ -91,6 +113,10 @@ module Vagrant
|
|||
index = triggers.index(trigger) unless match == true
|
||||
end
|
||||
|
||||
if trigger.type != type
|
||||
index = triggers.index(trigger)
|
||||
end
|
||||
|
||||
if index
|
||||
@logger.debug("Trigger #{trigger.id} will be ignored for #{guest_name}")
|
||||
triggers.delete_at(index)
|
||||
|
@ -110,10 +136,10 @@ module Vagrant
|
|||
@logger.debug("Running trigger #{trigger.id}...")
|
||||
|
||||
if trigger.name
|
||||
@machine.ui.info(I18n.t("vagrant.trigger.fire_with_name",
|
||||
@ui.info(I18n.t("vagrant.trigger.fire_with_name",
|
||||
name: trigger.name))
|
||||
else
|
||||
@machine.ui.info(I18n.t("vagrant.trigger.fire"))
|
||||
@ui.info(I18n.t("vagrant.trigger.fire"))
|
||||
end
|
||||
|
||||
if trigger.info
|
||||
|
@ -146,14 +172,14 @@ module Vagrant
|
|||
#
|
||||
# @param [String] message The string to be printed
|
||||
def info(message)
|
||||
@machine.ui.info(message)
|
||||
@ui.info(message)
|
||||
end
|
||||
|
||||
# Prints the given message at warn level for a trigger
|
||||
#
|
||||
# @param [String] message The string to be printed
|
||||
def warn(message)
|
||||
@machine.ui.warn(message)
|
||||
@ui.warn(message)
|
||||
end
|
||||
|
||||
# Runs a script on a guest
|
||||
|
@ -167,14 +193,14 @@ module Vagrant
|
|||
cmd = Shellwords.split(config.inline)
|
||||
end
|
||||
|
||||
@machine.ui.detail(I18n.t("vagrant.trigger.run.inline", command: config.inline))
|
||||
@ui.detail(I18n.t("vagrant.trigger.run.inline", command: config.inline))
|
||||
else
|
||||
cmd = File.expand_path(config.path, @env.root_path).shellescape
|
||||
args = Array(config.args)
|
||||
cmd << " #{args.join(' ')}" if !args.empty?
|
||||
cmd = Shellwords.split(cmd)
|
||||
|
||||
@machine.ui.detail(I18n.t("vagrant.trigger.run.script", path: config.path))
|
||||
@ui.detail(I18n.t("vagrant.trigger.run.script", path: config.path))
|
||||
end
|
||||
|
||||
# Pick an execution method to run the script or inline string with
|
||||
|
@ -199,22 +225,22 @@ module Vagrant
|
|||
options[:color] = :red if !config.keep_color
|
||||
end
|
||||
|
||||
@machine.ui.detail(data, options)
|
||||
@ui.detail(data, options)
|
||||
end
|
||||
if !exit_codes.include?(result.exit_code)
|
||||
raise Errors::TriggersBadExitCodes,
|
||||
code: result.exit_code
|
||||
end
|
||||
rescue => e
|
||||
@machine.ui.error(I18n.t("vagrant.errors.triggers_run_fail"))
|
||||
@machine.ui.error(e.message)
|
||||
@ui.error(I18n.t("vagrant.errors.triggers_run_fail"))
|
||||
@ui.error(e.message)
|
||||
|
||||
if on_error == :halt
|
||||
@logger.debug("Trigger run encountered an error. Halting on error...")
|
||||
raise e
|
||||
else
|
||||
@logger.debug("Trigger run encountered an error. Continuing on anyway...")
|
||||
@machine.ui.warn(I18n.t("vagrant.trigger.on_error_continue"))
|
||||
@ui.warn(I18n.t("vagrant.trigger.on_error_continue"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -258,12 +284,15 @@ module Vagrant
|
|||
#
|
||||
# @param [Integer] code Code to exit Vagrant on
|
||||
def trigger_abort(exit_code)
|
||||
@machine.ui.warn(I18n.t("vagrant.trigger.abort"))
|
||||
@ui.warn(I18n.t("vagrant.trigger.abort"))
|
||||
exit(exit_code)
|
||||
end
|
||||
|
||||
# Calls the given ruby block for execution
|
||||
#
|
||||
# TODO: Need to see what, if anything, we should do when
|
||||
# @machine is nil (i.e. a command trigger)
|
||||
#
|
||||
# @param [Proc] ruby_block
|
||||
def execute_ruby(ruby_block)
|
||||
ruby_block.call(@env, @machine)
|
||||
|
|
|
@ -44,7 +44,9 @@ module VagrantPlugins
|
|||
command.flatten!
|
||||
blk = block
|
||||
|
||||
if !block_given? && command.last.is_a?(Hash)
|
||||
if block_given? && command.last.is_a?(Hash)
|
||||
extra_cfg = command.pop
|
||||
elsif !block_given? && command.last.is_a?(Hash)
|
||||
# We were given a hash rather than a block,
|
||||
# so the last element should be the "config block"
|
||||
# and the rest are commands for the trigger
|
||||
|
@ -55,7 +57,7 @@ module VagrantPlugins
|
|||
end
|
||||
|
||||
command.each do |cmd|
|
||||
trigger = create_trigger(cmd, blk)
|
||||
trigger = create_trigger(cmd, blk, extra_cfg)
|
||||
@_before_triggers << trigger
|
||||
end
|
||||
end
|
||||
|
@ -69,7 +71,9 @@ module VagrantPlugins
|
|||
command.flatten!
|
||||
blk = block
|
||||
|
||||
if !block_given? && command.last.is_a?(Hash)
|
||||
if block_given? && command.last.is_a?(Hash)
|
||||
extra_cfg = command.pop
|
||||
elsif !block_given? && command.last.is_a?(Hash)
|
||||
# We were given a hash rather than a block,
|
||||
# so the last element should be the "config block"
|
||||
# and the rest are commands for the trigger
|
||||
|
@ -80,7 +84,7 @@ module VagrantPlugins
|
|||
end
|
||||
|
||||
command.each do |cmd|
|
||||
trigger = create_trigger(cmd, blk)
|
||||
trigger = create_trigger(cmd, blk, extra_cfg)
|
||||
@_after_triggers << trigger
|
||||
end
|
||||
end
|
||||
|
@ -95,13 +99,15 @@ module VagrantPlugins
|
|||
#
|
||||
# @param [Symbol] command Vagrant command to create trigger on
|
||||
# @param [Block] block The defined config block
|
||||
# @param [Hash] extra_cfg Extra configurations for a block defined trigger (Optional)
|
||||
# @return [VagrantConfigTrigger]
|
||||
def create_trigger(command, block)
|
||||
def create_trigger(command, block, extra_cfg=nil)
|
||||
trigger = VagrantConfigTrigger.new(command)
|
||||
if block.is_a?(Hash)
|
||||
trigger.set_options(block)
|
||||
else
|
||||
block.call(trigger, VagrantConfigTrigger)
|
||||
trigger.set_options(extra_cfg) if extra_cfg
|
||||
end
|
||||
return trigger
|
||||
end
|
||||
|
|
|
@ -9,6 +9,7 @@ module VagrantPlugins
|
|||
# Defaults
|
||||
DEFAULT_ON_ERROR = :halt
|
||||
DEFAULT_EXIT_CODE = 0
|
||||
VALID_TRIGGER_TYPES = [:command, :action].freeze
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# Config class for a given Trigger
|
||||
|
@ -89,6 +90,12 @@ module VagrantPlugins
|
|||
# @return [Proc]
|
||||
attr_accessor :ruby
|
||||
|
||||
# The type of trigger, which defines where it will fire. If not defined,
|
||||
# the option will default to `:action`
|
||||
#
|
||||
# @return [Symbol]
|
||||
attr_accessor :type
|
||||
|
||||
def initialize(command)
|
||||
@logger = Log4r::Logger.new("vagrant::config::vm::trigger::config")
|
||||
|
||||
|
@ -103,6 +110,7 @@ module VagrantPlugins
|
|||
@exit_codes = UNSET_VALUE
|
||||
@abort = UNSET_VALUE
|
||||
@ruby = UNSET_VALUE
|
||||
@type = UNSET_VALUE
|
||||
|
||||
# Internal options
|
||||
@id = SecureRandom.uuid
|
||||
|
@ -135,6 +143,7 @@ module VagrantPlugins
|
|||
@only_on = nil if @only_on == UNSET_VALUE
|
||||
@exit_codes = DEFAULT_EXIT_CODE if @exit_codes == UNSET_VALUE
|
||||
@abort = nil if @abort == UNSET_VALUE
|
||||
@type = :action if @type == UNSET_VALUE
|
||||
|
||||
@ruby_block = nil if @ruby_block == UNSET_VALUE
|
||||
@ruby = nil if @ruby == UNSET_VALUE
|
||||
|
@ -187,20 +196,38 @@ module VagrantPlugins
|
|||
if @abort == true
|
||||
@abort = 1
|
||||
end
|
||||
|
||||
if @type
|
||||
@type = @type.to_sym
|
||||
end
|
||||
end
|
||||
|
||||
# @return [Array] array of strings of error messages from config option validation
|
||||
def validate(machine)
|
||||
errors = _detected_errors
|
||||
|
||||
commands = []
|
||||
Vagrant.plugin("2").manager.commands.each do |key,data|
|
||||
commands.push(key)
|
||||
if @type && !VALID_TRIGGER_TYPES.include?(@type)
|
||||
errors << I18n.t("vagrant.config.triggers.bad_trigger_type",
|
||||
type: @type,
|
||||
trigger: @command,
|
||||
types: VALID_TRIGGER_TYPES.join(', '))
|
||||
end
|
||||
|
||||
if !commands.include?(@command) && @command != :all
|
||||
machine.ui.warn(I18n.t("vagrant.config.triggers.bad_command_warning",
|
||||
cmd: @command))
|
||||
if @type == :command || !@type
|
||||
commands = []
|
||||
Vagrant.plugin("2").manager.commands.each do |key,data|
|
||||
commands.push(key)
|
||||
end
|
||||
|
||||
if !commands.include?(@command) && @command != :all
|
||||
machine.ui.warn(I18n.t("vagrant.config.triggers.bad_command_warning",
|
||||
cmd: @command))
|
||||
end
|
||||
end
|
||||
|
||||
if @type == :action
|
||||
actions = []
|
||||
# Get every registered action hook and check if it includes the command defined
|
||||
end
|
||||
|
||||
if @run
|
||||
|
|
|
@ -296,7 +296,7 @@ en:
|
|||
abort: |-
|
||||
Vagrant has been configured to abort. Terminating now...
|
||||
start: |-
|
||||
Running triggers %{stage} %{action} ...
|
||||
Running %{type} triggers %{stage} %{action} ...
|
||||
fire_with_name: |-
|
||||
Running trigger: %{name}...
|
||||
fire: |-
|
||||
|
@ -1826,6 +1826,8 @@ en:
|
|||
values are exactly the same, only the name of the option has changed.
|
||||
ssh_config_missing: "`config` file must exist: %{path}"
|
||||
triggers:
|
||||
bad_trigger_type: |-
|
||||
The type '%{type}' defined for trigger '%{trigger}' is not valid. Must be one of the following types: '%{types}'
|
||||
bad_command_warning: |-
|
||||
The command '%{cmd}' was not found for this trigger.
|
||||
name_bad_type: |-
|
||||
|
|
|
@ -71,6 +71,7 @@ describe VagrantPlugins::Kernel_V2::VagrantConfigTrigger do
|
|||
cfg.only_on = :guest
|
||||
cfg.ignore = "up"
|
||||
cfg.abort = true
|
||||
cfg.type = "action"
|
||||
cfg.ruby do
|
||||
var = 1+1
|
||||
end
|
||||
|
@ -112,6 +113,11 @@ describe VagrantPlugins::Kernel_V2::VagrantConfigTrigger do
|
|||
|
||||
expect(cfg.abort).to eq(1)
|
||||
end
|
||||
|
||||
it "converts types to symbols" do
|
||||
cfg.finalize!
|
||||
expect(cfg.type).to eq(:action)
|
||||
end
|
||||
end
|
||||
|
||||
describe "defining a basic trigger config" do
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require File.expand_path("../../../base", __FILE__)
|
||||
|
||||
describe Vagrant::Action::Runner do
|
||||
let(:instance) { described_class.new }
|
||||
let(:instance) { described_class.new(action_name: "test") }
|
||||
|
||||
it "should raise an error if an invalid callable is given" do
|
||||
expect { instance.run(7) }.to raise_error(ArgumentError, /must be a callable/)
|
||||
|
@ -18,6 +18,7 @@ describe Vagrant::Action::Runner do
|
|||
raise Exception, "BANG"
|
||||
end
|
||||
end
|
||||
|
||||
callable = klass.new.method(:action)
|
||||
expect { instance.run(callable) }.to raise_error(Exception, "BANG")
|
||||
end
|
||||
|
@ -63,7 +64,7 @@ describe Vagrant::Action::Runner do
|
|||
result = env["data"]
|
||||
end
|
||||
|
||||
instance = described_class.new("data" => "bar")
|
||||
instance = described_class.new("data" => "bar", action_name: "test")
|
||||
instance.run(callable)
|
||||
expect(result).to eq("bar")
|
||||
end
|
||||
|
@ -74,7 +75,7 @@ describe Vagrant::Action::Runner do
|
|||
result = env["data"]
|
||||
end
|
||||
|
||||
instance = described_class.new { { "data" => "bar" } }
|
||||
instance = described_class.new { { "data" => "bar", action_name: "test" } }
|
||||
instance.run(callable)
|
||||
expect(result).to eq("bar")
|
||||
end
|
||||
|
|
|
@ -411,38 +411,6 @@ describe Vagrant::Machine do
|
|||
expect(subject.ui).to_not have_received(:warn)
|
||||
end
|
||||
end
|
||||
|
||||
context "with the vagrant-triggers community plugin" do
|
||||
it "should not call the internal trigger functions if installed" do
|
||||
action_name = :destroy
|
||||
callable = lambda { |_env| }
|
||||
|
||||
allow(provider).to receive(:action).with(action_name).and_return(callable)
|
||||
|
||||
# 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)
|
||||
instance.action(action_name)
|
||||
end
|
||||
|
||||
it "should call the internal trigger functions if not installed" do
|
||||
action_name = :destroy
|
||||
callable = lambda { |_env| }
|
||||
|
||||
allow(provider).to receive(:action).with(action_name).and_return(callable)
|
||||
allow(Vagrant::Plugin::Manager.instance).to receive(:installed_plugins)
|
||||
.and_return({})
|
||||
|
||||
expect(instance.instance_variable_get(:@triggers)).to receive(:fire_triggers).twice
|
||||
instance.action(action_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#action_raw" do
|
||||
|
|
|
@ -17,9 +17,10 @@ describe Vagrant::Plugin::V2::Trigger do
|
|||
allow(m).to receive(:state).and_return(state)
|
||||
end
|
||||
end
|
||||
let(:ui) { Vagrant::UI::Silent.new }
|
||||
let(:env) { {
|
||||
machine: machine,
|
||||
ui: Vagrant::UI::Silent.new,
|
||||
ui: ui,
|
||||
} }
|
||||
|
||||
let(:triggers) { VagrantPlugins::Kernel_V2::TriggerConfig.new }
|
||||
|
@ -36,19 +37,33 @@ describe Vagrant::Plugin::V2::Trigger do
|
|||
end
|
||||
|
||||
|
||||
let(:subject) { described_class.new(env, triggers, machine) }
|
||||
let(:subject) { described_class.new(env, triggers, machine, ui) }
|
||||
|
||||
context "#fire_triggers" do
|
||||
it "raises an error if an inproper stage is given" do
|
||||
expect{ subject.fire_triggers(:up, :not_real, "guest") }.
|
||||
expect{ subject.fire_triggers(:up, :not_real, "guest", :action) }.
|
||||
to raise_error(Vagrant::Errors::TriggersNoStageGiven)
|
||||
end
|
||||
|
||||
it "does not fire triggers if community plugin is detected" do
|
||||
allow(subject).to receive(:community_plugin_detected?).and_return(true)
|
||||
|
||||
expect(subject).not_to receive(:fire)
|
||||
subject.fire_triggers(:up, :before, "guest", :action)
|
||||
end
|
||||
|
||||
it "does fire triggers if community plugin is not detected" do
|
||||
allow(subject).to receive(:community_plugin_detected?).and_return(false)
|
||||
|
||||
expect(subject).to receive(:fire)
|
||||
subject.fire_triggers(:up, :before, "guest", :action)
|
||||
end
|
||||
end
|
||||
|
||||
context "#filter_triggers" do
|
||||
it "returns all triggers if no constraints" do
|
||||
before_triggers = triggers.before_triggers
|
||||
filtered_triggers = subject.send(:filter_triggers, before_triggers, "guest")
|
||||
filtered_triggers = subject.send(:filter_triggers, before_triggers, "guest", :action)
|
||||
expect(filtered_triggers).to eq(before_triggers)
|
||||
end
|
||||
|
||||
|
@ -59,7 +74,7 @@ describe Vagrant::Plugin::V2::Trigger do
|
|||
|
||||
after_triggers = triggers.after_triggers
|
||||
expect(after_triggers.size).to eq(3)
|
||||
subject.send(:filter_triggers, after_triggers, "ubuntu")
|
||||
subject.send(:filter_triggers, after_triggers, "ubuntu", :action)
|
||||
expect(after_triggers.size).to eq(2)
|
||||
end
|
||||
|
||||
|
@ -70,7 +85,7 @@ describe Vagrant::Plugin::V2::Trigger do
|
|||
|
||||
after_triggers = triggers.after_triggers
|
||||
expect(after_triggers.size).to eq(3)
|
||||
subject.send(:filter_triggers, after_triggers, "ubuntu-guest")
|
||||
subject.send(:filter_triggers, after_triggers, "ubuntu-guest", :action)
|
||||
expect(after_triggers.size).to eq(3)
|
||||
end
|
||||
|
||||
|
@ -81,7 +96,7 @@ describe Vagrant::Plugin::V2::Trigger do
|
|||
|
||||
after_triggers = triggers.after_triggers
|
||||
expect(after_triggers.size).to eq(3)
|
||||
subject.send(:filter_triggers, after_triggers, "ubuntu-guest")
|
||||
subject.send(:filter_triggers, after_triggers, "ubuntu-guest", :action)
|
||||
expect(after_triggers.size).to eq(3)
|
||||
end
|
||||
end
|
||||
|
@ -101,7 +116,7 @@ describe Vagrant::Plugin::V2::Trigger do
|
|||
|
||||
it "prints messages at INFO" do
|
||||
output = ""
|
||||
allow(machine.ui).to receive(:info) do |data|
|
||||
allow(ui).to receive(:info) do |data|
|
||||
output << data
|
||||
end
|
||||
|
||||
|
@ -115,7 +130,7 @@ describe Vagrant::Plugin::V2::Trigger do
|
|||
|
||||
it "prints messages at WARN" do
|
||||
output = ""
|
||||
allow(machine.ui).to receive(:warn) do |data|
|
||||
allow(ui).to receive(:warn) do |data|
|
||||
output << data
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue