Add local-exec push

This commit is contained in:
Seth Vargo 2014-11-14 15:51:35 -05:00
parent 9d1a43c766
commit 612eeb2265
7 changed files with 252 additions and 0 deletions

View File

@ -0,0 +1,37 @@
module VagrantPlugins
module LocalExecPush
class Config < Vagrant.plugin("2", :config)
# The command (as a string) to execute.
# @return [String]
attr_accessor :command
def initialize
@command = UNSET_VALUE
end
def finalize!
@command = nil if @command == UNSET_VALUE
end
def validate(machine)
errors = _detected_errors
if missing?(@command)
errors << I18n.t("local_exec_push.errors.missing_attribute",
attribute: "command",
)
end
{ "Local Exec push" => errors }
end
private
# Determine if the given string is "missing" (blank)
# @return [true, false]
def missing?(obj)
obj.to_s.strip.empty?
end
end
end
end

View File

@ -0,0 +1,13 @@
module VagrantPlugins
module LocalExecPush
module Errors
class Error < Vagrant::Errors::VagrantError
error_namespace("local_exec_push.errors")
end
class CommandFailed < Error
error_key(:command_failed)
end
end
end
end

View File

@ -0,0 +1,18 @@
en:
local_exec_push:
errors:
command_failed: |-
The following command exited with a non-zero exit status:
%{cmd}
stdout: %{stdout}
stderr: %{stderr}
missing_attribute: |-
Missing required attribute '%{attribute}'. The Vagrant Local Exec Push
plugin requires you set this attribute. Please set this attribute in
your Vagrantfile, for example:
config.push.define "local-exec" do |push|
push.%{attribute} = "..."
end

View File

@ -0,0 +1,33 @@
require "vagrant"
module VagrantPlugins
module LocalExecPush
class Plugin < Vagrant.plugin("2")
name "local-exec"
description <<-DESC
Run a local command or script to push
DESC
config(:local_exec, :push) do
require File.expand_path("../config", __FILE__)
init!
Config
end
push(:local_exec) do
require File.expand_path("../push", __FILE__)
init!
Push
end
protected
def self.init!
return if defined?(@_init)
I18n.load_path << File.expand_path("../locales/en.yml", __FILE__)
I18n.reload!
@_init = true
end
end
end
end

View File

@ -0,0 +1,28 @@
require "vagrant/util/subprocess"
require_relative "errors"
module VagrantPlugins
module LocalExecPush
class Push < Vagrant.plugin("2", :push)
def push
execute!(config.command)
end
# Execute the command, raising an exception if it fails.
# @return [Vagrant::Util::Subprocess::Result]
def execute!(*cmd)
result = Vagrant::Util::Subprocess.execute(*cmd)
if result.exit_code != 0
raise Errors::CommandFailed,
cmd: cmd.join(" "),
stdout: result.stdout,
stderr: result.stderr
end
result
end
end
end
end

View File

@ -0,0 +1,45 @@
require_relative "../../../base"
require Vagrant.source_root.join("plugins/pushes/local-exec/config")
describe VagrantPlugins::LocalExecPush::Config do
include_context "unit"
before(:all) do
I18n.load_path << Vagrant.source_root.join("plugins/pushes/local-exec/locales/en.yml")
I18n.reload!
end
let(:machine) { double("machine") }
describe "#command" do
it "defaults to nil" do
subject.finalize!
expect(subject.command).to be(nil)
end
end
describe "#validate" do
before do
allow(machine).to receive(:env)
.and_return(double("env",
root_path: "",
))
subject.command = "echo"
end
let(:result) { subject.validate(machine) }
let(:errors) { result["Local Exec push"] }
context "when the command is missing" do
it "returns an error" do
subject.command = ""
subject.finalize!
expect(errors).to include(I18n.t("local_exec_push.errors.missing_attribute",
attribute: "command",
))
end
end
end
end

View File

@ -0,0 +1,78 @@
require_relative "../../../base"
require Vagrant.source_root.join("plugins/pushes/local-exec/push")
describe VagrantPlugins::LocalExecPush::Push do
include_context "unit"
before(:all) do
I18n.load_path << Vagrant.source_root.join("plugins/pushes/local-exec/locales/en.yml")
I18n.reload!
end
let(:env) { isolated_environment }
let(:config) do
double("config",
command: "echo",
)
end
subject { described_class.new(env, config) }
describe "#push" do
before do
allow(subject).to receive(:execute!)
end
it "executes the command" do
expect(subject).to receive(:execute!)
.with(config.command)
subject.push
end
end
describe "#execute!" do
let(:exit_code) { 0 }
let(:stdout) { "This is the output" }
let(:stderr) { "This is the errput" }
let(:process) do
double("process",
exit_code: exit_code,
stdout: stdout,
stderr: stderr,
)
end
before do
allow(Vagrant::Util::Subprocess).to receive(:execute)
.and_return(process)
end
it "creates a subprocess" do
expect(Vagrant::Util::Subprocess).to receive(:execute)
expect { subject.execute! }.to_not raise_error
end
it "returns the resulting process" do
expect(subject.execute!).to be(process)
end
context "when the exit code is non-zero" do
let(:exit_code) { 1 }
it "raises an exception" do
klass = VagrantPlugins::LocalExecPush::Errors::CommandFailed
cmd = ["foo", "bar"]
expect { subject.execute!(*cmd) }.to raise_error(klass) { |error|
expect(error.message).to eq(I18n.t("local_exec_push.errors.command_failed",
cmd: cmd.join(" "),
stdout: stdout,
stderr: stderr,
))
}
end
end
end
end