1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
|
require "vagrant"
require File.expand_path("../vm_trigger", __FILE__)
module VagrantPlugins
module Kernel_V2
class TriggerConfig < Vagrant.plugin("2", :config)
# The TriggerConfig class is what gets called when a user
# defines a new trigger in their Vagrantfile. The two entry points are
# either `config.trigger.before` or `config.trigger.after`.
def initialize
@logger = Log4r::Logger.new("vagrant::config::trigger")
# Internal State
@_before_triggers = [] # An array of VagrantConfigTrigger objects
@_after_triggers = [] # An array of VagrantConfigTrigger objects
end
#-------------------------------------------------------------------
# Trigger before/after functions
#-------------------------------------------------------------------
#
# Commands are expected to be ether:
# - splat
# + config.trigger.before :up, :destroy, :halt do |trigger|....
# - array
# + config.trigger.before [:up, :destroy, :halt] do |trigger|....
#
# Config is expected to be given as a block, or the last parameter as a hash
#
# - block
# + config.trigger.before :up, :destroy, :halt do |trigger|
# trigger.option = "option"
# end
# - hash
# + config.trigger.before :up, :destroy, :halt, options: "option"
# Reads in and parses Vagrant command whitelist and settings for a defined
# trigger
#
# @param [Symbol] command Vagrant command to create trigger on
# @param [Block] block The defined before block
def before(*command, &block)
command.flatten!
blk = block
if !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
blk = command.pop
elsif !block_given?
raise Vagrant::Errors::TriggersNoBlockGiven,
command: command
end
command.each do |cmd|
trigger = create_trigger(cmd, blk)
@_before_triggers << trigger
end
end
# Reads in and parses Vagrant command whitelist and settings for a defined
# trigger
#
# @param [Symbol] command Vagrant command to create trigger on
# @param [Block] block The defined after block
def after(*command, &block)
command.flatten!
blk = block
if !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
blk = command.pop
elsif !block_given?
raise Vagrant::Errors::TriggersNoBlockGiven,
command: command
end
command.each do |cmd|
trigger = create_trigger(cmd, blk)
@_after_triggers << trigger
end
end
#-------------------------------------------------------------------
# Internal methods, don't call these.
#-------------------------------------------------------------------
# Creates a new trigger config. If a block is given, parse that block
# by calling it with the created trigger. Otherwise set the options if it's
# a hash.
#
# @param [Symbol] command Vagrant command to create trigger on
# @param [Block] block The defined config block
# @return [VagrantConfigTrigger]
def create_trigger(command, block)
trigger = VagrantConfigTrigger.new(command)
if block.is_a?(Hash)
trigger.set_options(block)
else
block.call(trigger, VagrantConfigTrigger)
end
return trigger
end
def merge(other)
super.tap do |result|
new_before_triggers = []
new_after_triggers = []
other_defined_before_triggers = other.instance_variable_get(:@_before_triggers)
other_defined_after_triggers = other.instance_variable_get(:@_after_triggers)
@_before_triggers.each do |bt|
other_bft = other_defined_before_triggers.find { |o| bt.id == o.id }
if other_bft
# Override, take it
other_bft = bt.merge(other_bft)
# Preserve order, always
bt = other_bft
other_defined_before_triggers.delete(other_bft)
end
new_before_triggers << bt.dup
end
other_defined_before_triggers.each do |obt|
new_before_triggers << obt.dup
end
result.instance_variable_set(:@_before_triggers, new_before_triggers)
@_after_triggers.each do |at|
other_aft = other_defined_after_triggers.find { |o| at.id == o.id }
if other_aft
# Override, take it
other_aft = at.merge(other_aft)
# Preserve order, always
at = other_aft
other_defined_after_triggers.delete(other_aft)
end
new_after_triggers << at.dup
end
other_defined_after_triggers.each do |oat|
new_after_triggers << oat.dup
end
result.instance_variable_set(:@_after_triggers, new_after_triggers)
end
end
# Iterates over all defined triggers and finalizes their config objects
def finalize!
if !@_before_triggers.empty?
@_before_triggers.map { |t| t.finalize! }
end
if !@_after_triggers.empty?
@_after_triggers.map { |t| t.finalize! }
end
end
# Validate Trigger Arrays
def validate(machine)
errors = _detected_errors
@_before_triggers.each do |bt|
error = bt.validate(machine)
errors.concat error if !error.empty?
end
@_after_triggers.each do |at|
error = at.validate(machine)
errors.concat error if !error.empty?
end
{"trigger" => errors}
end
# return [Array]
def before_triggers
@_before_triggers
end
# return [Array]
def after_triggers
@_after_triggers
end
# The String representation of this Trigger.
#
# @return [String]
def to_s
"trigger"
end
end
end
end
|