Only allow the all special value to be matched when requested

This prevents the all special value from being matched on the
non-defined raw action names when the typed triggers support
is enabled.
This commit is contained in:
Chris Roberts 2020-06-12 17:09:31 -07:00
parent 916655dbd3
commit f26440ee38
6 changed files with 21 additions and 20 deletions

View File

@ -252,18 +252,18 @@ module Vagrant
# and after specific provider actions (like :up, :halt, etc) and
# are different from true action triggers
if env[:triggers]
if !env[:triggers].find(env[:raw_action_name], :before, machine_name, :action).empty?
if !env[:triggers].find(env[:raw_action_name], :before, machine_name, :action, all: true).empty?
hook.prepend(Vagrant::Action::Builtin::Trigger,
env[:raw_action_name], env[:triggers], :before, :action)
env[:raw_action_name], env[:triggers], :before, :action, all: true)
end
if !env[:triggers].find(env[:raw_action_name], :after, machine_name, :action).empty?
if !env[:triggers].find(env[:raw_action_name], :after, machine_name, :action, all: true).empty?
# NOTE: These after triggers need to be delayed before running to
# allow the rest of the call stack to complete before being
# run. The delayed action is prepended to the stack (not appended)
# to ensure it is called first, which results in it properly
# waiting for everything to finish before itself completing.
builder = self.class.build(Vagrant::Action::Builtin::Trigger,
env[:raw_action_name], env[:triggers], :after, :action)
env[:raw_action_name], env[:triggers], :after, :action, all: true)
hook.prepend(Vagrant::Action::Builtin::Delayed, builder)
end
end

View File

@ -8,13 +8,14 @@ module Vagrant
# @param [Vagrant::Plugin::V2::Triger] triggers Trigger object
# @param [Symbol] timing When trigger should fire (:before/:after)
# @param [Symbol] type Type of trigger
def initialize(app, env, name, triggers, timing, type=:action)
def initialize(app, env, name, triggers, timing, type=:action, all: false)
@app = app
@env = env
@triggers = triggers
@name = name
@timing = timing
@type = type
@all = all
if ![:before, :after].include?(timing)
raise ArgumentError,
@ -26,7 +27,7 @@ module Vagrant
machine = env[:machine]
machine_name = machine.name if machine
@triggers.fire(@name, @timing, machine_name, @type)
@triggers.fire(@name, @timing, machine_name, @type, all: @all)
# Carry on
@app.call(env)
end

View File

@ -37,7 +37,7 @@ module Vagrant
# @param [Symbol] stage :before or :after
# @param [String] guest The guest that invoked firing the triggers
# @param [Symbol] type Type of trigger to fire (:action, :hook, :command)
def fire(name, stage, guest, type)
def fire(name, stage, guest, type, all: false)
if community_plugin_detected?
@logger.warn("Community plugin `vagrant-triggers detected, so core triggers will not fire")
return
@ -50,7 +50,7 @@ module Vagrant
name = name.to_sym
# get all triggers matching action
triggers = find(name, stage, guest, type)
triggers = find(name, stage, guest, type, all: all)
if !triggers.empty?
@logger.info("Firing trigger for #{type} #{name} on guest #{guest}")
@ -66,19 +66,19 @@ module Vagrant
# @param [String] guest The guest that invoked firing the triggers
# @param [Symbol] type Type of trigger to fire
# @return [Array]
def find(name, stage, guest, type)
def find(name, stage, guest, type, all: false)
triggers = nil
name = nameify(name)
if stage == :before
triggers = config.before_triggers.select do |t|
(t.command.respond_to?(:to_sym) && t.command.to_sym == :all && !t.ignore.include?(name.to_sym)) ||
(all && t.command.respond_to?(:to_sym) && t.command.to_sym == :all && !t.ignore.include?(name.to_sym)) ||
(type == :hook && matched_hook?(t.command, name)) ||
nameify(t.command) == name
end
elsif stage == :after
triggers = config.after_triggers.select do |t|
(t.command.respond_to?(:to_sym) && t.command.to_sym == :all && !t.ignore.include?(name.to_sym)) ||
(all && t.command.respond_to?(:to_sym) && t.command.to_sym == :all && !t.ignore.include?(name.to_sym)) ||
(type == :hook && matched_hook?(t.command, name)) ||
nameify(t.command) == name
end

View File

@ -674,7 +674,7 @@ describe Vagrant::Action::Builder do
context "when trigger has been defined for raw action" do
before do
expect(triggers).to receive(:find).with(raw_action_name, timing, nil, :action).
expect(triggers).to receive(:find).with(raw_action_name, timing, nil, :action, all: true).
and_return([true])
end

View File

@ -28,7 +28,7 @@ describe Vagrant::Action::Builtin::Trigger do
end
it "should fire triggers without machine name" do
expect(triggers).to receive(:fire).with(name, timing, nil, type)
expect(triggers).to receive(:fire).with(name, timing, nil, type, anything)
subject.call(env)
end
@ -36,7 +36,7 @@ describe Vagrant::Action::Builtin::Trigger do
let(:machine) { double("machine", name: "machine-name") }
it "should include machine name when firing triggers" do
expect(triggers).to receive(:fire).with(name, timing, "machine-name", type)
expect(triggers).to receive(:fire).with(name, timing, "machine-name", type, anything)
subject.call(env)
end
end

View File

@ -99,11 +99,11 @@ describe Vagrant::Plugin::V2::Trigger do
[:destroy, :halt, :provision, :reload, :resume, :suspend, :up].each do |supported_action|
it "should locate trigger when before #{supported_action} action is requested" do
expect(subject.find(supported_action, :before, "guest", :action)).not_to be_empty
expect(subject.find(supported_action, :before, "guest", :action, all: true)).not_to be_empty
end
it "should locate trigger when after #{supported_action} action is requested" do
expect(subject.find(supported_action, :after, "guest", :action)).not_to be_empty
expect(subject.find(supported_action, :after, "guest", :action, all: true)).not_to be_empty
end
end
@ -111,19 +111,19 @@ describe Vagrant::Plugin::V2::Trigger do
let(:ignores) { [:halt, :up] }
it "should not locate trigger when before command is ignored" do
expect(subject.find(:up, :before, "guest", :action)).to be_empty
expect(subject.find(:up, :before, "guest", :action, all: true)).to be_empty
end
it "should not locate trigger when after command is ignored" do
expect(subject.find(:halt, :after, "guest", :action)).to be_empty
expect(subject.find(:halt, :after, "guest", :action, all: true)).to be_empty
end
it "should locate trigger when before command is not ignored" do
expect(subject.find(:provision, :before, "guest", :action)).not_to be_empty
expect(subject.find(:provision, :before, "guest", :action, all: true)).not_to be_empty
end
it "should locate trigger when after command is not ignored" do
expect(subject.find(:provision, :after, "guest", :action)).not_to be_empty
expect(subject.find(:provision, :after, "guest", :action, all: true)).not_to be_empty
end
end
end