vagrant-triggers 0.4.4 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 82d8d42ba2873b8ff1d16d07b4415c7b408c0cfa
4
- data.tar.gz: 393eaa0899b5e070d5e8bcec79da77f1f19bd92b
3
+ metadata.gz: feda77ab141c553c1886766fd74d69ddfb0b2153
4
+ data.tar.gz: 0b73b4f744e7f5c0aec0a769eaa90629076c2c98
5
5
  SHA512:
6
- metadata.gz: 56647d8624db454ebb33e9c46a1e0199e7c38e9e818f7d88ce371aaf83e295e6a70a26b5ecb5e4d9cd224679ede171b7f7206d6cf781f39a3ea7382b3900ca49
7
- data.tar.gz: 2e4fea84758569ce2a2e114e0555922678223ae2bb8832768aef71bf8fd01e24bdb6c442fee84f0371a3dc6e610d970b76a77b457adde560f56dbe3d917d1f31
6
+ metadata.gz: 5ec60cd4c036eaedf2f64d9f5e63559d00dfc39d7a29eab6cd7e38b4de3a1d9d5acb4d0dc65d8ad02c2e5767d5c69c9ce22bacb610cf609084466edcad85a491
7
+ data.tar.gz: 8d05d7c3abf88ccabc6a93b2542183a36bfdfe9d7aea0abdba3e41c2fbfc047e8a3fbab2eafc61af1fc06165cdb2fc35a37978fcdaab5307bc9a2b0e7f80f370
data/.gitignore CHANGED
@@ -3,6 +3,8 @@
3
3
  .bundle
4
4
  pkg/*
5
5
  Gemfile.lock
6
+ Gemfile.dev
7
+ Gemfile.dev.lock
6
8
 
7
9
  coverage
8
10
 
data/.travis.yml CHANGED
@@ -7,11 +7,13 @@ before_install:
7
7
  - gem uninstall -ax bundler
8
8
  - gem install bundler -v 1.5.3
9
9
  env:
10
- - VAGRANT_VERSION=v1.6.5
10
+ - VAGRANT_VERSION=v1.7.1
11
11
  matrix:
12
12
  include:
13
13
  - env: VAGRANT_VERSION=master
14
14
  rvm: 2.0.0
15
+ - env: VAGRANT_VERSION=v1.6.5
16
+ rvm: 2.0.0
15
17
  - env: VAGRANT_VERSION=v1.5.4
16
18
  rvm: 2.0.0
17
19
  - env: VAGRANT_VERSION=v1.4.3
@@ -23,3 +25,4 @@ matrix:
23
25
  allow_failures:
24
26
  - env: VAGRANT_VERSION=master
25
27
  rvm: 2.0.0
28
+ sudo: false
data/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ ## 0.5.0 (December 29, 2014)
2
+
3
+ **BEHAVIOURAL CHANGES:**
4
+
5
+ - The ```:stdout``` option now defaults to true.
6
+
7
+ NEW FEATURES:
8
+
9
+ - New option ```:stderr``` for displaying standard error from scripts.
10
+ - The special action ```:ALL``` can be used when a trigger should always run [(#23)](https://github.com/emyl/vagrant-triggers/issues/23)
11
+ - Actions can be blacklisted using ```config.trigger.blacklist```.
12
+ - Triggers can be run as a provisioner [(#21)](https://github.com/emyl/vagrant-triggers/issues/21)
13
+
14
+ IMPROVEMENTS:
15
+
16
+ - Do not buffer command output and better integrate in core UI [(#18)](https://github.com/emyl/vagrant-triggers/issues/18)
17
+
18
+ BUG FIXES:
19
+
20
+ - Handle MS-DOS commands better [(#27)](https://github.com/emyl/vagrant-triggers/issues/27)
21
+
1
22
  ## 0.4.4 (December 12, 2014)
2
23
 
3
24
  BUG FIXES:
data/README.md CHANGED
@@ -43,11 +43,27 @@ The ```instead_of``` trigger could also be aliased as ```reject```.
43
43
 
44
44
  The first argument is the command in which the trigger will be tied. It could be an array (e.g. ```[:up, :resume]```) in case of multiple commands.
45
45
 
46
+ Starting from version 0.5.0, triggers can also be run as a provisioner:
47
+
48
+ ```ruby
49
+ Vagrant.configure("2") do |config|
50
+ # Your existing Vagrant configuration
51
+ ...
52
+
53
+ config.vm.provision "trigger", :option => "value" do |trigger|
54
+ trigger.fire do
55
+ run "script"
56
+ end
57
+ end
58
+ end
59
+ ```
60
+
46
61
  ### Options
47
62
 
48
63
  * ```:append_to_path => ["dir", "dir"]```: additional places where looking for scripts. See [this wiki page](https://github.com/emyl/vagrant-triggers/wiki/The-:append_to_path-option) for details.
49
- * ```:force => true```: continue even if one of the scripts fails (exits with non-zero code)
50
- * ```:stdout => true```: display script output
64
+ * ```:force => true|false```: continue even if one of the scripts fails (exits with non-zero code). Defaults to false.
65
+ * ```:stderr => true|false```: display standard error from scripts. Defaults to true.
66
+ * ```:stdout => true|false```: display standard output from scripts. Defaults to true.
51
67
  * ```:vm => ["vm1", /vm[2-3]/]```: fire only for matching virtual machines. Value can be a string, a regexp or an array of strings and/or regexps.
52
68
 
53
69
  ### Trigger block DSL
@@ -109,6 +125,3 @@ To run the plugin's tests:
109
125
  $ bundle exec rake
110
126
 
111
127
  You can now fork this repository, make your changes and send a pull request.
112
-
113
-
114
- [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/emyl/vagrant-triggers/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
@@ -4,10 +4,11 @@ require "vagrant-triggers/plugin"
4
4
  module VagrantPlugins
5
5
  module Triggers
6
6
  lib_path = Pathname.new(File.expand_path("../vagrant-triggers", __FILE__))
7
- autoload :Action, lib_path.join("action")
8
- autoload :DSL, lib_path.join("dsl")
9
- autoload :Config, lib_path.join("config")
10
- autoload :Errors, lib_path.join("errors")
7
+ autoload :Action, lib_path.join("action")
8
+ autoload :DSL, lib_path.join("dsl")
9
+ autoload :Config, lib_path.join("config")
10
+ autoload :Errors, lib_path.join("errors")
11
+ autoload :Provisioner, lib_path.join("provisioner")
11
12
 
12
13
  # This returns the path to the source of this plugin.
13
14
  #
@@ -31,18 +31,13 @@ module VagrantPlugins
31
31
  trigger_env.each { |k, v| @logger.debug("-- #{k}: #{v}")}
32
32
 
33
33
  # Loop through all defined triggers checking for matches.
34
+ triggers_config = @env[:machine].config.trigger
34
35
  triggers_to_fire = [].tap do |triggers|
35
- @env[:machine].config.trigger.triggers.each do |trigger|
36
- next if trigger[:action] != trigger_env[:action]
36
+ triggers_config.triggers.each do |trigger|
37
+ next if trigger[:action] != :ALL && trigger[:action] != trigger_env[:action]
37
38
  next if trigger[:condition] != trigger_env[:condition]
38
39
 
39
- if trigger[:options][:vm]
40
- match = false
41
- Array(trigger[:options][:vm]).each do |pattern|
42
- match = true if trigger_env[:vm].match(Regexp.new(pattern))
43
- end
44
- next unless match
45
- end
40
+ next if triggers_config.blacklist.include?(trigger_env[:action])
46
41
 
47
42
  triggers << trigger
48
43
  end
@@ -55,8 +50,11 @@ module VagrantPlugins
55
50
 
56
51
  triggers_to_fire.each do |trigger|
57
52
  if trigger[:proc]
58
- dsl = DSL.new(@env[:ui], @env[:machine], trigger[:options])
59
- dsl.instance_eval &trigger[:proc]
53
+ begin
54
+ dsl = DSL.new(@env[:machine], trigger[:options])
55
+ dsl.instance_eval &trigger[:proc]
56
+ rescue Errors::NotMatchingMachine
57
+ end
60
58
  else
61
59
  @logger.debug("Trigger command not found.")
62
60
  end
@@ -1,48 +1,10 @@
1
1
  module VagrantPlugins
2
2
  module Triggers
3
- class Config < Vagrant.plugin("2", :config)
4
- attr_reader :triggers
5
-
6
- def initialize
7
- @triggers = []
8
- end
9
-
10
- def after(actions, options = {}, &block)
11
- add_trigger(actions, :after, options, block)
12
- end
13
-
14
- def before(actions, options = {}, &block)
15
- add_trigger(actions, :before, options, block)
16
- end
17
-
18
- def instead_of(actions, options = {}, &block)
19
- add_trigger(actions, :instead_of, options, block)
20
- end
21
- alias_method :reject, :instead_of
22
-
23
- def merge(other)
24
- super.tap do |result|
25
- result.instance_variable_set(:@triggers, @triggers + other.triggers)
26
- end
27
- end
28
-
29
- def validate(machine)
30
- errors = []
31
-
32
- if @__invalid_methods && !@__invalid_methods.empty?
33
- errors << I18n.t("vagrant.config.common.bad_field", :fields => @__invalid_methods.to_a.sort.join(", "))
34
- end
35
-
36
- { "triggers" => errors }
37
- end
38
-
39
- private
40
-
41
- def add_trigger(actions, condition, options, proc)
42
- Array(actions).each do |action|
43
- @triggers << { :action => action, :condition => condition, :options => options, :proc => proc }
44
- end
45
- end
3
+ module Config
4
+ # Autoload farm
5
+ config_root = Pathname.new(File.expand_path("../config", __FILE__))
6
+ autoload :Provisioner, config_root.join("provisioner")
7
+ autoload :Trigger, config_root.join("trigger")
46
8
  end
47
9
  end
48
10
  end
@@ -0,0 +1,22 @@
1
+ module VagrantPlugins
2
+ module Triggers
3
+ module Config
4
+ class Provisioner < Vagrant.plugin("2", :config)
5
+ attr_reader :options
6
+ attr_reader :trigger_body
7
+
8
+ def initialize
9
+ @options = {}
10
+ end
11
+
12
+ def fire(&block)
13
+ @trigger_body = block
14
+ end
15
+
16
+ def set_options(options)
17
+ @options = options
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,61 @@
1
+ module VagrantPlugins
2
+ module Triggers
3
+ module Config
4
+ class Trigger < Vagrant.plugin("2", :config)
5
+ attr_reader :triggers
6
+
7
+ def initialize
8
+ @blacklist = []
9
+ @options = { :stdout => true, :stderr => true }
10
+ @triggers = []
11
+ end
12
+
13
+ def after(actions, options = {}, &block)
14
+ add_trigger(actions, :after, options, block)
15
+ end
16
+
17
+ def before(actions, options = {}, &block)
18
+ add_trigger(actions, :before, options, block)
19
+ end
20
+
21
+ def blacklist(actions = nil)
22
+ if actions
23
+ Array(actions).each { |action| @blacklist << action.to_s }
24
+ @blacklist.uniq!
25
+ end
26
+ @blacklist
27
+ end
28
+
29
+ def instead_of(actions, options = {}, &block)
30
+ add_trigger(actions, :instead_of, options, block)
31
+ end
32
+ alias_method :reject, :instead_of
33
+
34
+ def merge(other)
35
+ super.tap do |result|
36
+ result.instance_variable_set(:@blacklist, @blacklist + other.blacklist)
37
+ result.instance_variable_set(:@triggers, @triggers + other.triggers)
38
+ end
39
+ end
40
+
41
+ def validate(machine)
42
+ errors = []
43
+
44
+ if @__invalid_methods && !@__invalid_methods.empty?
45
+ errors << I18n.t("vagrant.config.common.bad_field", :fields => @__invalid_methods.to_a.sort.join(", "))
46
+ end
47
+
48
+ { "triggers" => errors }
49
+ end
50
+
51
+ private
52
+
53
+ def add_trigger(actions, condition, options, proc)
54
+ Array(actions).each do |action|
55
+ @triggers << { :action => action, :condition => condition, :options => @options.merge(options), :proc => proc }
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -1,16 +1,30 @@
1
1
  require "bundler"
2
2
  require "log4r"
3
- require "shellwords"
4
3
  require "vagrant/util/subprocess"
5
4
 
6
5
  module VagrantPlugins
7
6
  module Triggers
8
7
  class DSL
9
- def initialize(ui, machine, options = {})
8
+ def initialize(machine, options = {})
9
+ if options[:vm]
10
+ match = false
11
+ Array(options[:vm]).each do |pattern|
12
+ match = true if machine.name.match(Regexp.new(pattern))
13
+ end
14
+ raise Errors::NotMatchingMachine unless match
15
+ end
16
+
17
+ @buffer = Hash.new("")
10
18
  @logger = Log4r::Logger.new("vagrant::plugins::triggers::dsl")
11
19
  @machine = machine
12
20
  @options = options
13
- @ui = ui
21
+ @ui = machine.ui
22
+
23
+ @command_output = lambda do |channel, data, options|
24
+ ui_method = (channel == :stdout) ? :info : :error
25
+ @buffer[channel] += data
26
+ @ui.send(ui_method, data) if options[channel]
27
+ end
14
28
  end
15
29
 
16
30
  def error(message, *opts)
@@ -18,36 +32,38 @@ module VagrantPlugins
18
32
  end
19
33
 
20
34
  def run(raw_command, options = {})
21
- info I18n.t("vagrant_triggers.action.trigger.executing_command", :command => raw_command)
22
- command = Shellwords.shellsplit(raw_command)
35
+ command = shellsplit(raw_command)
36
+ options.merge!(@options) { |key, old, new| old }
37
+ info I18n.t("vagrant_triggers.action.trigger.executing_command", :command => command.join(" "))
23
38
  env_backup = ENV.to_hash
24
39
  begin
25
40
  result = nil
26
41
  Bundler.with_clean_env do
27
42
  build_environment
28
- result = Vagrant::Util::Subprocess.execute(command[0], *command[1..-1])
43
+ @buffer.clear
44
+ result = Vagrant::Util::Subprocess.execute(command[0], *command[1..-1], :notify => [:stdout, :stderr]) do |channel, data|
45
+ @command_output.call(channel, data, options)
46
+ end
29
47
  end
48
+ info I18n.t("vagrant_triggers.action.trigger.command_finished")
30
49
  rescue Vagrant::Errors::CommandUnavailable, Vagrant::Errors::CommandUnavailableWindows
31
50
  raise Errors::CommandUnavailable, :command => command[0]
32
51
  ensure
33
52
  ENV.replace(env_backup)
34
53
  end
35
- process_result(raw_command, result, @options.merge(options))
54
+ process_result(raw_command, result, options)
36
55
  end
37
56
  alias_method :execute, :run
38
57
 
39
58
  def run_remote(raw_command, options = {})
59
+ options.merge!(@options) { |key, old, new| old }
40
60
  info I18n.t("vagrant_triggers.action.trigger.executing_remote_command", :command => raw_command)
41
- stderr = ""
42
- stdout = ""
43
- exit_code = @machine.communicate.sudo(raw_command, :elevated => true, :good_exit => (0..255).to_a) do |type, data|
44
- if type == :stderr
45
- stderr += data
46
- elsif type == :stdout
47
- stdout += data
48
- end
61
+ @buffer.clear
62
+ exit_code = @machine.communicate.sudo(raw_command, :elevated => true, :good_exit => (0..255).to_a) do |channel, data|
63
+ @command_output.call(channel, data, options)
49
64
  end
50
- process_result(raw_command, Vagrant::Util::Subprocess::Result.new(exit_code, stdout, stderr), @options.merge(options))
65
+ info I18n.t("vagrant_triggers.action.trigger.remote_command_finished")
66
+ process_result(raw_command, Vagrant::Util::Subprocess::Result.new(exit_code, @buffer[:stdout], @buffer[:stderr]), options)
51
67
  end
52
68
  alias_method :execute_remote, :run_remote
53
69
 
@@ -84,11 +100,27 @@ module VagrantPlugins
84
100
  if result.exit_code != 0 && !options[:force]
85
101
  raise Errors::CommandFailed, :command => command, :stderr => result.stderr
86
102
  end
87
- if options[:stdout]
88
- info I18n.t("vagrant_triggers.action.trigger.command_output", :output => result.stdout)
89
- end
90
103
  result.stdout
91
104
  end
105
+
106
+ # This is a custom version of Shellwords.shellsplit adapted for handling MS-DOS commands.
107
+ #
108
+ # Basically escape sequences are left intact if the platform is Windows.
109
+ def shellsplit(line)
110
+ words = []
111
+ field = ''
112
+ line.scan(/\G\s*(?>([^\s\\\'\"]+)|'([^\']*)'|"((?:[^\"\\]|\\.)*)"|(\\.?)|(\S))(\s|\z)?/) do |word, sq, dq, esc, garbage, sep|
113
+ raise ArgumentError, "Unmatched double quote: #{line.inspect}" if garbage
114
+ token = (word || sq || (dq || esc))
115
+ token.gsub!(/\\(.)/, '\1') unless Vagrant::Util::Platform.windows?
116
+ field << token
117
+ if sep
118
+ words << field
119
+ field = ''
120
+ end
121
+ end
122
+ words
123
+ end
92
124
  end
93
125
  end
94
126
  end
@@ -16,6 +16,9 @@ module VagrantPlugins
16
16
  class DSLError < VagrantTriggerError
17
17
  error_key(:dsl_error)
18
18
  end
19
+
20
+ class NotMatchingMachine < VagrantTriggerError
21
+ end
19
22
  end
20
23
  end
21
24
  end
@@ -34,12 +34,22 @@ module VagrantPlugins
34
34
  end
35
35
 
36
36
  config(:trigger) do
37
- require_relative "config"
38
- Config
37
+ require_relative "config/trigger"
38
+ Config::Trigger
39
+ end
40
+
41
+ config(:trigger, :provisioner) do
42
+ require_relative "config/provisioner"
43
+ Config::Provisioner
44
+ end
45
+
46
+ provisioner(:trigger) do
47
+ require_relative "provisioner"
48
+ Provisioner
39
49
  end
40
50
 
41
51
  # This initializes the I18n load path so that the plugin specific
42
- # transations work.
52
+ # translations work.
43
53
  def self.init_i18n
44
54
  I18n.load_path << File.expand_path("locales/en.yml", Triggers.source_root)
45
55
  I18n.reload!
@@ -0,0 +1,26 @@
1
+ module VagrantPlugins
2
+ module Triggers
3
+ class Provisioner < Vagrant.plugin("2", :provisioner)
4
+ def initialize(machine, config)
5
+ @config = config
6
+ begin
7
+ @dsl = DSL.new(machine, @config.options)
8
+ rescue Errors::NotMatchingMachine
9
+ ENV["VAGRANT_NO_TRIGGERS"] = "1"
10
+ end
11
+ end
12
+
13
+ def configure(root_config)
14
+ end
15
+
16
+ def provision
17
+ unless ENV["VAGRANT_NO_TRIGGERS"]
18
+ @dsl.instance_eval &@config.trigger_body
19
+ end
20
+ end
21
+
22
+ def cleanup
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module Triggers
3
- VERSION = "0.4.4"
3
+ VERSION = "0.5.0"
4
4
  end
5
5
  end
data/locales/en.yml CHANGED
@@ -2,15 +2,14 @@ en:
2
2
  vagrant_triggers:
3
3
  action:
4
4
  trigger:
5
- command_output: |-
6
- Command output:
7
- ---------------
8
- %{output}
9
- ---------------
5
+ command_finished: |-
6
+ Command execution finished.
10
7
  executing_command: |-
11
8
  Executing command "%{command}"...
12
9
  executing_remote_command: |-
13
10
  Executing remote command "%{command}"...
11
+ remote_command_finished: |-
12
+ Remote command execution finished.
14
13
  running_triggers: |-
15
14
  Running triggers %{condition} %{action}...
16
15
  errors:
data/spec/spec_helper.rb CHANGED
@@ -5,3 +5,9 @@ require "vagrant"
5
5
  require_relative "../lib/vagrant-triggers"
6
6
 
7
7
  VagrantPlugins::Triggers::Plugin.init_i18n
8
+
9
+ RSpec.configure do |config|
10
+ config.mock_with :rspec do |mocks|
11
+ mocks.syntax = :should
12
+ end
13
+ end
@@ -5,16 +5,17 @@ describe VagrantPlugins::Triggers::Action::Trigger do
5
5
  let(:env) { { :action_name => action_name, :machine => machine, :machine_action => machine_action, :ui => ui } }
6
6
  let(:condition) { double("condition") }
7
7
  let(:action_name) { double("action_name") }
8
- let(:machine) { double("machine") }
8
+ let(:machine) { double("machine", :ui => ui) }
9
9
  let(:machine_action) { double("machine_action") }
10
10
 
11
11
  let(:ui) { double("ui", :info => info) }
12
12
  let(:info) { double("info") }
13
13
 
14
- before do
14
+ before :each do
15
15
  trigger_block = Proc.new { nil }
16
16
  @triggers = [ { :action => machine_action, :condition => condition, :options => { }, :proc => trigger_block } ]
17
17
  machine.stub(:name)
18
+ machine.stub_chain(:config, :trigger, :blacklist).and_return([])
18
19
  machine.stub_chain(:config, :trigger, :triggers).and_return(@triggers)
19
20
  end
20
21
 
@@ -35,7 +36,15 @@ describe VagrantPlugins::Triggers::Action::Trigger do
35
36
 
36
37
  it "should fire trigger when all conditions are satisfied" do
37
38
  dsl = double("dsl")
38
- VagrantPlugins::Triggers::DSL.stub(:new).with(ui, machine, @triggers.first[:options]).and_return(dsl)
39
+ VagrantPlugins::Triggers::DSL.stub(:new).with(machine, @triggers.first[:options]).and_return(dsl)
40
+ dsl.should_receive(:instance_eval).and_yield
41
+ described_class.new(app, env, condition).call(env)
42
+ end
43
+
44
+ it "should fire trigger when condition matches and action is :ALL" do
45
+ @triggers[0][:action] = :ALL
46
+ dsl = double("dsl")
47
+ VagrantPlugins::Triggers::DSL.stub(:new).with(machine, @triggers.first[:options]).and_return(dsl)
39
48
  dsl.should_receive(:instance_eval).and_yield
40
49
  described_class.new(app, env, condition).call(env)
41
50
  end
@@ -52,14 +61,20 @@ describe VagrantPlugins::Triggers::Action::Trigger do
52
61
  described_class.new(app, env, condition).call(env)
53
62
  end
54
63
 
64
+ it "shouldn't fire trigger when the action is blacklisted" do
65
+ machine.stub_chain(:config, :trigger, :blacklist).and_return([machine_action])
66
+ VagrantPlugins::Triggers::DSL.should_not_receive(:new)
67
+ described_class.new(app, env, condition).call(env)
68
+ end
69
+
55
70
  it "shouldn't fire trigger when condition doesn't match" do
56
- @triggers[0][:condition] = "blah"
71
+ @triggers[0][:condition] = :blah
57
72
  VagrantPlugins::Triggers::DSL.should_not_receive(:new)
58
73
  described_class.new(app, env, condition).call(env)
59
74
  end
60
75
 
61
76
  it "shouldn't fire trigger when action doesn't match" do
62
- @triggers[0][:action] = "blah"
77
+ @triggers[0][:action] = :blah
63
78
  VagrantPlugins::Triggers::DSL.should_not_receive(:new)
64
79
  described_class.new(app, env, condition).call(env)
65
80
  end
@@ -70,45 +85,8 @@ describe VagrantPlugins::Triggers::Action::Trigger do
70
85
  described_class.new(app, env, :instead_of).call(env)
71
86
  end
72
87
 
73
- context ":vm option" do
74
- before do
75
- machine.stub(:name).and_return(:vm1)
76
- end
77
-
78
- it "should fire trigger when :vm option match" do
79
- @triggers[0][:options][:vm] = "vm1"
80
- VagrantPlugins::Triggers::DSL.should_receive(:new)
81
- described_class.new(app, env, condition).call(env)
82
- end
83
-
84
- it "shouldn't fire trigger when :vm option doesn't match" do
85
- @triggers[0][:options][:vm] = "vm2"
86
- VagrantPlugins::Triggers::DSL.should_not_receive(:new)
87
- described_class.new(app, env, condition).call(env)
88
- end
89
-
90
- it "should fire trigger when :vm option is an array and one of the elements match" do
91
- @triggers[0][:options][:vm] = ["vm1", "vm2"]
92
- VagrantPlugins::Triggers::DSL.should_receive(:new)
93
- described_class.new(app, env, condition).call(env)
94
- end
95
-
96
- it "shouldn't fire trigger when :vm option is an array and no element match" do
97
- @triggers[0][:options][:vm] = ["vm2", "vm3"]
98
- VagrantPlugins::Triggers::DSL.should_not_receive(:new)
99
- described_class.new(app, env, condition).call(env)
100
- end
101
-
102
- it "should fire trigger when :vm option is a regex and the pattern match" do
103
- @triggers[0][:options][:vm] = /^vm/
104
- VagrantPlugins::Triggers::DSL.should_receive(:new)
105
- described_class.new(app, env, condition).call(env)
106
- end
107
-
108
- it "shouldn't fire trigger when :vm option is a regex and the pattern doesn't match" do
109
- @triggers[0][:options][:vm] = /staging/
110
- VagrantPlugins::Triggers::DSL.should_not_receive(:new)
111
- described_class.new(app, env, condition).call(env)
112
- end
88
+ it "should handle gracefully a not matching :vm option" do
89
+ VagrantPlugins::Triggers::DSL.stub(:new).and_raise(VagrantPlugins::Triggers::Errors::NotMatchingMachine)
90
+ expect { described_class.new(app, env, condition).call(env) }.not_to raise_exception()
113
91
  end
114
92
  end
@@ -0,0 +1,21 @@
1
+ require "spec_helper"
2
+
3
+ describe VagrantPlugins::Triggers::Config::Provisioner do
4
+ let(:config) { described_class.new }
5
+
6
+ describe "fire" do
7
+ it "should record trigger code" do
8
+ code = Proc.new { "foo" }
9
+ config.fire(&code)
10
+ expect(config.trigger_body).to eq(code)
11
+ end
12
+ end
13
+
14
+ describe "set_options" do
15
+ it "should set options" do
16
+ options = { :foo => "bar", :baz => "bat" }
17
+ config.set_options(options)
18
+ expect(config.options).to eq(options)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,95 @@
1
+ require "spec_helper"
2
+
3
+ describe VagrantPlugins::Triggers::Config::Trigger do
4
+ let(:config) { described_class.new }
5
+ let(:machine) { double("machine") }
6
+
7
+ describe "defaults" do
8
+ subject do
9
+ config.tap do |o|
10
+ o.finalize!
11
+ end
12
+ expect(config.triggers).to eq([])
13
+ end
14
+
15
+ it "should default :stdout option to true" do
16
+ config.before(:up) { run "ls" }
17
+ expect(config.triggers.first[:options][:stdout]).to eq(true)
18
+ end
19
+
20
+ it "should default :stderr option to true" do
21
+ config.before(:up) { run "ls" }
22
+ expect(config.triggers.first[:options][:stderr]).to eq(true)
23
+ end
24
+
25
+ it "should override options" do
26
+ config.before(:up, :stdout => false) { run "ls" }
27
+ expect(config.triggers.first[:options][:stdout]).to eq(false)
28
+ end
29
+ end
30
+
31
+ describe "add triggers" do
32
+ it "should add before triggers" do
33
+ config.before(:up) { run "ls" }
34
+ expect(config.triggers.size).to eq(1)
35
+ end
36
+
37
+ it "should add instead_of triggers" do
38
+ config.instead_of(:up) { run "ls" }
39
+ expect(config.triggers.size).to eq(1)
40
+ end
41
+
42
+ it "should add after triggers" do
43
+ config.after(:up) { run "ls" }
44
+ expect(config.triggers.size).to eq(1)
45
+ end
46
+ end
47
+
48
+ describe "blacklist" do
49
+ it "should blacklist an action" do
50
+ config.blacklist(:up)
51
+ expect(config.blacklist.size).to eq(1)
52
+ end
53
+
54
+ it "should blacklist multiple actions" do
55
+ config.blacklist([:up, :destroy])
56
+ expect(config.blacklist.size).to eq(2)
57
+ end
58
+
59
+ it "should convert symbols to strings" do
60
+ config.blacklist(:up)
61
+ expect(config.blacklist).to eq(["up"])
62
+ end
63
+
64
+ it "should blacklist an action only once" do
65
+ config.blacklist(["up", "destroy"])
66
+ config.blacklist(:up)
67
+ expect(config.blacklist).to eq(["up", "destroy"])
68
+ end
69
+ end
70
+
71
+ describe "accept multiple entries" do
72
+ it "should record multiple entries" do
73
+ config.before(:up) { run "ls" }
74
+ config.after(:up) { run "ls" }
75
+ expect(config.triggers.size).to eq(2)
76
+ end
77
+
78
+ it "should record multiple entries if the action is an array" do
79
+ config.before([:up, :halt]) { run "ls" }
80
+ expect(config.triggers.size).to eq(2)
81
+ end
82
+ end
83
+
84
+ describe "validation" do
85
+ it "should validate" do
86
+ config.finalize!
87
+ expect(config.validate(machine)["triggers"].size).to eq(0)
88
+ end
89
+
90
+ it "shouldn't accept invalid methods" do
91
+ config.foo "bar"
92
+ expect(config.validate(machine)["triggers"].size).to eq(1)
93
+ end
94
+ end
95
+ end
@@ -5,17 +5,53 @@ describe VagrantPlugins::Triggers::DSL do
5
5
  let(:result) { double("result", :exit_code => 0, :stderr => stderr) }
6
6
  let(:stderr) { double("stderr") }
7
7
 
8
- let(:machine) { double("machine") }
8
+ let(:machine) { double("machine", :ui => ui) }
9
9
  let(:ui) { double("ui", :info => info) }
10
10
  let(:info) { double("info") }
11
11
 
12
12
  before do
13
13
  @command = "foo"
14
- @dsl = described_class.new(ui, machine, {})
14
+ @dsl = described_class.new(machine, {})
15
15
 
16
16
  result.stub(:stdout => "Some output")
17
17
  end
18
18
 
19
+ context ":vm option" do
20
+ before do
21
+ machine.stub(:name => :vm1)
22
+ end
23
+
24
+ it "should raise no exception when :vm option match" do
25
+ options = { :vm => "vm1" }
26
+ expect { described_class.new(machine, options) }.not_to raise_error()
27
+ end
28
+
29
+ it "should raise NotMatchingMachine when :vm option doesn't match" do
30
+ options = { :vm => "vm2" }
31
+ expect { described_class.new(machine, options) }.to raise_error(VagrantPlugins::Triggers::Errors::NotMatchingMachine)
32
+ end
33
+
34
+ it "should raise no exception when :vm option is an array and one of the elements match" do
35
+ options = { :vm => ["vm1", "vm2"] }
36
+ expect { described_class.new(machine, options) }.not_to raise_error()
37
+ end
38
+
39
+ it "should raise NotMatchingMachine when :vm option is an array and no element match" do
40
+ options = { :vm => ["vm2", "vm3"] }
41
+ expect { described_class.new(machine, options) }.to raise_error(VagrantPlugins::Triggers::Errors::NotMatchingMachine)
42
+ end
43
+
44
+ it "should raise no exception when :vm option is a regex and the pattern match" do
45
+ options = { :vm => /^vm/ }
46
+ expect { described_class.new(machine, options) }.not_to raise_error()
47
+ end
48
+
49
+ it "should raise NotMatchingMachine when :vm option is a regex and the pattern doesn't match" do
50
+ options = { :vm => /staging/ }
51
+ expect { described_class.new(machine, options) }.to raise_error(VagrantPlugins::Triggers::Errors::NotMatchingMachine)
52
+ end
53
+ end
54
+
19
55
  context "error" do
20
56
  it "should raise a DSL error on UI error" do
21
57
  ui.should_receive(:error).with("Error message")
@@ -33,6 +69,7 @@ describe VagrantPlugins::Triggers::DSL do
33
69
  context "run a regular command" do
34
70
  before do
35
71
  Vagrant::Util::Subprocess.stub(:execute => result)
72
+ @options = { :notify => [:stdout, :stderr] }
36
73
  end
37
74
 
38
75
  it "should raise an error if executed command exits with non-zero code" do
@@ -41,15 +78,14 @@ describe VagrantPlugins::Triggers::DSL do
41
78
  end
42
79
 
43
80
  it "shouldn't raise an error if executed command exits with non-zero code but :force option was specified" do
44
- dsl = described_class.new(ui, machine, :force => true)
81
+ dsl = described_class.new(machine, :force => true)
45
82
  result.stub(:exit_code => 1)
46
83
  expect { dsl.run(@command) }.not_to raise_error()
47
84
  end
48
85
 
49
- it "should display output if :stdout option was specified" do
50
- dsl = described_class.new(ui, machine, :stdout => true)
51
- ui.should_receive(:info).with(/Some output/)
52
- dsl.run(@command)
86
+ it "should return standard output" do
87
+ dsl = described_class.new(machine)
88
+ expect(dsl.run(@command)).to eq("Some output")
53
89
  end
54
90
 
55
91
  it "should pass VAGRANT_NO_TRIGGERS environment variable to the command" do
@@ -59,6 +95,19 @@ describe VagrantPlugins::Triggers::DSL do
59
95
  end
60
96
  @dsl.run(@command)
61
97
  end
98
+
99
+ it "should remove escape sequences on UNIX Bourne Shell" do
100
+ command = "echo foo\\ bar"
101
+ Vagrant::Util::Subprocess.should_receive(:execute).with("echo", "foo bar", @options)
102
+ @dsl.run(command)
103
+ end
104
+
105
+ it "should not remove escape sequences on MS-DOS Shell" do
106
+ Vagrant::Util::Platform.stub(:windows? => true)
107
+ command = "echo foo\\ bar"
108
+ Vagrant::Util::Subprocess.should_receive(:execute).with("echo", "foo\\ bar", @options)
109
+ @dsl.run(command)
110
+ end
62
111
  end
63
112
 
64
113
  context "run a command not in the PATH" do
@@ -83,14 +132,14 @@ describe VagrantPlugins::Triggers::DSL do
83
132
  end
84
133
 
85
134
  it "should honor the :append_to_path option and restore original path after execution" do
86
- dsl = described_class.new(ui, machine, :append_to_path => @tmp_dir)
135
+ dsl = described_class.new(machine, :append_to_path => @tmp_dir)
87
136
  original_path = ENV["PATH"]
88
137
  dsl.run(@command)
89
138
  expect(ENV["PATH"]).to eq(original_path)
90
139
  end
91
140
 
92
141
  it "should accept an array for the :append_to_path option" do
93
- dsl = described_class.new(ui, machine, :append_to_path => [@tmp_dir, @tmp_dir])
142
+ dsl = described_class.new(machine, :append_to_path => [@tmp_dir, @tmp_dir])
94
143
  expect { dsl.run(@command) }.not_to raise_error()
95
144
  end
96
145
  end
@@ -162,15 +211,14 @@ describe VagrantPlugins::Triggers::DSL do
162
211
  end
163
212
 
164
213
  it "shouldn't raise an error if executed command exits with non-zero code but :force option was specified" do
165
- dsl = described_class.new(ui, machine, :force => true)
214
+ dsl = described_class.new(machine, :force => true)
166
215
  result.stub(:exit_code => 1)
167
216
  expect { dsl.run_remote(@command) }.not_to raise_error()
168
217
  end
169
218
 
170
- it "should display output if :stdout option was specified" do
171
- dsl = described_class.new(ui, machine, :stdout => true)
172
- ui.should_receive(:info).with(/Some output/)
173
- dsl.run_remote(@command)
219
+ it "should return standard output" do
220
+ dsl = described_class.new(machine)
221
+ expect(dsl.run_remote(@command)).to eq("Some output")
174
222
  end
175
223
  end
176
224
  end
@@ -0,0 +1,41 @@
1
+ require "spec_helper"
2
+
3
+ describe VagrantPlugins::Triggers::Provisioner do
4
+ let(:config) { double("config", :options => options, :trigger_body => Proc.new { "foo" }) }
5
+ let(:machine) { double("machine") }
6
+ let(:options) { double("options") }
7
+
8
+ before :each do
9
+ ENV["VAGRANT_NO_TRIGGERS"] = nil
10
+ end
11
+
12
+ describe "constructor" do
13
+ it "should create a DSL object" do
14
+ VagrantPlugins::Triggers::DSL.should_receive(:new).with(machine, options)
15
+ described_class.new(machine, config)
16
+ end
17
+
18
+ it "should handle gracefully a not matching :vm option" do
19
+ VagrantPlugins::Triggers::DSL.stub(:new).and_raise(VagrantPlugins::Triggers::Errors::NotMatchingMachine)
20
+ expect { described_class.new(machine, config) }.not_to raise_exception()
21
+ end
22
+ end
23
+
24
+ describe "provision" do
25
+ before :each do
26
+ @dsl = double("dsl")
27
+ VagrantPlugins::Triggers::DSL.stub(:new).with(machine, options).and_return(@dsl)
28
+ end
29
+
30
+ it "should run code against DSL object" do
31
+ @dsl.should_receive(:instance_eval).and_yield
32
+ described_class.new(machine, config).provision
33
+ end
34
+
35
+ it "should not run code if VAGRANT_NO_TRIGGERS is set" do
36
+ ENV["VAGRANT_NO_TRIGGERS"] = "1"
37
+ @dsl.should_not_receive(:instance_eval)
38
+ described_class.new(machine, config).provision
39
+ end
40
+ end
41
+ end
@@ -51,5 +51,5 @@ Gem::Specification.new do |spec|
51
51
  spec.add_dependency "bundler", "~> 1.3"
52
52
 
53
53
  spec.add_development_dependency "rake"
54
- spec.add_development_dependency "rspec", "< 3"
54
+ spec.add_development_dependency "rspec"
55
55
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-triggers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emiliano Ticci
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-12 00:00:00.000000000 Z
11
+ date: 2014-12-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -42,16 +42,16 @@ dependencies:
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - <
45
+ - - '>='
46
46
  - !ruby/object:Gem::Version
47
- version: '3'
47
+ version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - <
52
+ - - '>='
53
53
  - !ruby/object:Gem::Version
54
- version: '3'
54
+ version: '0'
55
55
  description: This plugin allow the definition of arbitrary scripts that will run on
56
56
  the host before and/or after Vagrant commands.
57
57
  email: emiticci@gmail.com
@@ -63,10 +63,13 @@ files:
63
63
  - Gemfile
64
64
  - lib/vagrant-triggers/action/trigger.rb
65
65
  - lib/vagrant-triggers/action.rb
66
+ - lib/vagrant-triggers/config/provisioner.rb
67
+ - lib/vagrant-triggers/config/trigger.rb
66
68
  - lib/vagrant-triggers/config.rb
67
69
  - lib/vagrant-triggers/dsl.rb
68
70
  - lib/vagrant-triggers/errors.rb
69
71
  - lib/vagrant-triggers/plugin.rb
72
+ - lib/vagrant-triggers/provisioner.rb
70
73
  - lib/vagrant-triggers/version.rb
71
74
  - lib/vagrant-triggers.rb
72
75
  - LICENSE.txt
@@ -75,8 +78,10 @@ files:
75
78
  - README.md
76
79
  - spec/spec_helper.rb
77
80
  - spec/vagrant-triggers/action/trigger_spec.rb
78
- - spec/vagrant-triggers/config_spec.rb
81
+ - spec/vagrant-triggers/config/provisioner_spec.rb
82
+ - spec/vagrant-triggers/config/trigger_spec.rb
79
83
  - spec/vagrant-triggers/dsl_spec.rb
84
+ - spec/vagrant-triggers/provisioner_spec.rb
80
85
  - spec/vagrant-triggers/vagrant_spec.rb
81
86
  - vagrant-triggers.gemspec
82
87
  - .gitignore
@@ -108,6 +113,8 @@ summary: Triggers for Vagrant commands.
108
113
  test_files:
109
114
  - spec/spec_helper.rb
110
115
  - spec/vagrant-triggers/action/trigger_spec.rb
111
- - spec/vagrant-triggers/config_spec.rb
116
+ - spec/vagrant-triggers/config/provisioner_spec.rb
117
+ - spec/vagrant-triggers/config/trigger_spec.rb
112
118
  - spec/vagrant-triggers/dsl_spec.rb
119
+ - spec/vagrant-triggers/provisioner_spec.rb
113
120
  - spec/vagrant-triggers/vagrant_spec.rb
@@ -1,58 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe VagrantPlugins::Triggers::Config do
4
- let(:config) { described_class.new }
5
- let(:machine) { double("machine") }
6
-
7
- describe "defaults" do
8
- subject do
9
- config.tap do |o|
10
- o.finalize!
11
- end
12
- end
13
-
14
- its("triggers") { should eq [] }
15
- end
16
-
17
- describe "add triggers" do
18
- it "should add before triggers" do
19
- config.before(:up) { run "ls" }
20
- expect(config.triggers).to have(1).item
21
- end
22
-
23
- it "should add instead_of triggers" do
24
- config.instead_of(:up) { run "ls" }
25
- expect(config.triggers).to have(1).item
26
- end
27
-
28
- it "should add after triggers" do
29
- config.after(:up) { run "ls" }
30
- expect(config.triggers).to have(1).item
31
- end
32
- end
33
-
34
- describe "accept multiple entries" do
35
- it "should record multiple entries" do
36
- config.before(:up) { run "ls" }
37
- config.after(:up) { run "ls" }
38
- expect(config.triggers).to have(2).items
39
- end
40
-
41
- it "should record multiple entries if the action is an array" do
42
- config.before([:up, :halt]) { run "ls" }
43
- expect(config.triggers).to have(2).items
44
- end
45
- end
46
-
47
- describe "validation" do
48
- it "should validate" do
49
- config.finalize!
50
- expect(config.validate(machine)["triggers"]).to have(:no).items
51
- end
52
-
53
- it "shouldn't accept invalid methods" do
54
- config.foo "bar"
55
- expect(config.validate(machine)["triggers"]).to have(1).item
56
- end
57
- end
58
- end