From efffc5f2f7a1b9374ff980c6bb30b0a47d403d9a Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 29 Oct 2014 09:39:26 -0700 Subject: [PATCH] push/harmony: basic push implementation --- plugins/pushes/harmony/errors.rb | 13 +++ plugins/pushes/harmony/plugin.rb | 2 + plugins/pushes/harmony/push.rb | 46 +++++++- test/unit/plugins/pushes/harmony/push_test.rb | 103 ++++++++++++++++++ 4 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 plugins/pushes/harmony/errors.rb create mode 100644 test/unit/plugins/pushes/harmony/push_test.rb diff --git a/plugins/pushes/harmony/errors.rb b/plugins/pushes/harmony/errors.rb new file mode 100644 index 000000000..9eb590ff3 --- /dev/null +++ b/plugins/pushes/harmony/errors.rb @@ -0,0 +1,13 @@ +module VagrantPlugins + module HarmonyPush + module Errors + class Error < Vagrant::Errors::VagrantError + error_namespace("harmony_push.errors") + end + + class UploaderNotFound < Error + error_key(:uploader_error) + end + end + end +end diff --git a/plugins/pushes/harmony/plugin.rb b/plugins/pushes/harmony/plugin.rb index a0c013f82..bcf662c01 100644 --- a/plugins/pushes/harmony/plugin.rb +++ b/plugins/pushes/harmony/plugin.rb @@ -2,6 +2,8 @@ require "vagrant" module VagrantPlugins module HarmonyPush + autoload :Errors, File.expand_path("../errors", __FILE__) + class Plugin < Vagrant.plugin("2") name "harmony" description <<-DESC diff --git a/plugins/pushes/harmony/push.rb b/plugins/pushes/harmony/push.rb index 20f1c355e..5a3907249 100644 --- a/plugins/pushes/harmony/push.rb +++ b/plugins/pushes/harmony/push.rb @@ -1,8 +1,52 @@ +require "vagrant/util/safe_exec" +require "vagrant/util/subprocess" +require "vagrant/util/which" + module VagrantPlugins module HarmonyPush class Push < Vagrant.plugin("2", :push) + UPLOADER_BIN = "harmony-upload" + def push - puts "pushed" + uploader = self.uploader_path + + # If we didn't find the uploader binary it is a critical error + raise Errors::UploaderNotFound if !uploader + + # We found it. Build up the command and the args. + execute(uploader) + return 0 + end + + # Executes the uploader with the proper flags based on the configuration. + # This function shouldn't return since it will exec, but might return + # if we're on a system that doesn't support exec, so handle that properly. + def execute(uploader) + cmd = [] + cmd << "-vcs" if @config.vcs + cmd += @config.include.map { |v| ["-include", v] } if !@config.include.empty? + cmd += @config.exclude.map { |v| ["-exclude", v] } if !@config.exclude.empty? + cmd << @config.app + cmd << @config.dir + Vagrant::Util::SafeExec.exec(uploader, *cmd.flatten) + end + + # This returns the path to the uploader binary, or nil if it can't + # be found. + # + # @return [String] + def uploader_path + # Determine the uploader path + uploader = @config.uploader_path + if uploader + return uploader + end + + if Vagrant.in_installer? + # TODO: look up uploader in embedded dir + else + return Vagrant::Util::Which.which(UPLOADER_BIN) + end end end end diff --git a/test/unit/plugins/pushes/harmony/push_test.rb b/test/unit/plugins/pushes/harmony/push_test.rb new file mode 100644 index 000000000..9b386370c --- /dev/null +++ b/test/unit/plugins/pushes/harmony/push_test.rb @@ -0,0 +1,103 @@ +require_relative "../../../base" + +require Vagrant.source_root.join("plugins/pushes/harmony/config") +require Vagrant.source_root.join("plugins/pushes/harmony/push") + +describe VagrantPlugins::HarmonyPush::Push do + include_context "unit" + + let(:config) do + VagrantPlugins::HarmonyPush::Config.new.tap do |c| + c.finalize! + end + end + + let(:machine) { double("machine") } + + subject { described_class.new(machine, config) } + + before do + # Stub this right away to avoid real execs + allow(Vagrant::Util::SafeExec).to receive(:exec) + end + + describe "#push" do + it "pushes with the uploader" do + allow(subject).to receive(:uploader_path).and_return("foo") + + expect(subject).to receive(:execute).with("foo") + + subject.push + end + + it "raises an exception if the uploader couldn't be found" do + expect(subject).to receive(:uploader_path).and_return(nil) + + expect { subject.push }.to raise_error( + VagrantPlugins::HarmonyPush::Errors::UploaderNotFound) + end + end + + describe "#execute" do + let(:app) { "foo/bar" } + + before do + config.app = app + end + + it "sends the basic flags" do + expect(Vagrant::Util::SafeExec).to receive(:exec). + with("foo", "-vcs", app, ".") + + subject.execute("foo") + end + + it "doesn't send VCS if disabled" do + expect(Vagrant::Util::SafeExec).to receive(:exec). + with("foo", app, ".") + + config.vcs = false + subject.execute("foo") + end + + it "sends includes" do + expect(Vagrant::Util::SafeExec).to receive(:exec). + with("foo", "-vcs", "-include", "foo", "-include", "bar", app, ".") + + config.include = ["foo", "bar"] + subject.execute("foo") + end + + it "sends excludes" do + expect(Vagrant::Util::SafeExec).to receive(:exec). + with("foo", "-vcs", "-exclude", "foo", "-exclude", "bar", app, ".") + + config.exclude = ["foo", "bar"] + subject.execute("foo") + end + end + + describe "#uploader_path" do + it "should return the configured path if set" do + config.uploader_path = "foo" + expect(subject.uploader_path).to eq("foo") + end + + it "should look up the uploader via PATH if not set" do + allow(Vagrant).to receive(:in_installer?).and_return(false) + + expect(Vagrant::Util::Which).to receive(:which). + with(described_class.const_get(:UPLOADER_BIN)). + and_return("bar") + + expect(subject.uploader_path).to eq("bar") + end + + it "should return nil if its not found anywhere" do + allow(Vagrant).to receive(:in_installer?).and_return(false) + allow(Vagrant::Util::Which).to receive(:which).and_return(nil) + + expect(subject.uploader_path).to be_nil + end + end +end