Super primitive implementation of Environment#push

This commit is contained in:
Seth Vargo 2014-10-23 16:01:43 -04:00
parent b6c5ca6b7a
commit 03b8105571
8 changed files with 184 additions and 17 deletions

View File

@ -539,6 +539,51 @@ module Vagrant
end end
end end
# This executes the push with the given name, raising any exceptions that
# occur.
#
def push(name=nil)
@logger.info("Getting push: #{name}")
if vagrantfile.pushes.nil? || vagrantfile.pushes.empty?
raise Vagrant::Errors::PushesNotDefined
end
if name.nil?
if vagrantfile.pushes.length != 1
raise Vagrant::Errors::PushStrategyNotProvided,
pushes: vagrantfile.pushes
end
name = vagrantfile.pushes.first
else
if !vagrantfile.pushes.include?(name.to_sym)
raise Vagrant::Errors::PushStrategyNotDefined,
name: name,
pushes: vagrantfile.pushes
end
end
push_registry = Vagrant.plugin("2").manager.pushes
push_config = vagrantfile.push(name)
push_config.each do |strategy, config_blocks|
plugin, options = push_registry.get(strategy)
# TODO: What do we do with options?
# options
if plugin.nil?
raise Vagrant::Errors::PushStrategyNotLoaded,
name: strategy,
pushes: push_registry.keys
end
# TODO: This should take a plugin configuration, not a list of config
# blocks, or should it?
plugin.new(self, config_blocks).push
end
end
# This returns a machine with the proper provider for this environment. # This returns a machine with the proper provider for this environment.
# The machine named by `name` must be in this environment. # The machine named by `name` must be in this environment.
# #

View File

@ -564,6 +564,10 @@ module Vagrant
error_key(:push_strategy_not_defined) error_key(:push_strategy_not_defined)
end end
class PushStrategyNotLoaded < VagrantError
error_key(:push_strategy_not_loaded)
end
class PushStrategyNotProvided < VagrantError class PushStrategyNotProvided < VagrantError
error_key(:push_strategy_not_provided) error_key(:push_strategy_not_provided)
end end

View File

@ -247,6 +247,20 @@ module Vagrant
nil nil
end end
# Returns the list of defined pushes in this Vagrantfile.
#
# @return [Array<Symbol>]
def pushes
@config.push.defined_pushes
end
# Get the push by the given name.
#
# @return [idk]
def push(name)
@config.push.get_push(name)
end
protected protected
def find_vagrantfile(search_path) def find_vagrantfile(search_path)

View File

@ -17,13 +17,14 @@ module VagrantPlugins
argv = parse_options(opts) argv = parse_options(opts)
return if !argv return if !argv
name, options = argv name = argv[0]
pushes = @env.pushes pushes = @env.pushes
# TODO: this logic is 100% duplicated in Enviroment#push - should we
# just not validate here?
validate_pushes!(pushes, name) validate_pushes!(pushes, name)
@logger.debug("'push' environment with strategy: `#{name}'") @logger.debug("'push' environment with strategy: `#{name}'")
@env.push(name) @env.push(name)
0 0
@ -50,7 +51,7 @@ module VagrantPlugins
raise Vagrant::Errors::PushStrategyNotProvided, pushes: pushes raise Vagrant::Errors::PushStrategyNotProvided, pushes: pushes
end end
else else
if !pushes.has_key?(name.to_sym) if !pushes.key?(name.to_sym)
raise Vagrant::Errors::PushStrategyNotDefined, raise Vagrant::Errors::PushStrategyNotDefined,
name: name, name: name,
pushes: pushes pushes: pushes

View File

@ -0,0 +1,99 @@
require "vagrant"
module VagrantPlugins
module Kernel_V2
class PushConfig < Vagrant.plugin("2", :config)
VALID_OPTIONS = [:strategy].freeze
attr_accessor :name
def initialize
# Internal state
@__defined_pushes = {}
@__finalized = false
end
def finalize!
@__finalized = true
end
# Define a new push in the Vagrantfile with the given name.
#
# @example
# vm.push.define "ftp"
#
# @example
# vm.push.define "ftp" do |s|
# s.host = "..."
# end
#
# @example
# vm.push.define "production", strategy: "docker" do |s|
# # ...
# end
#
# @param [#to_sym] name The name of the this strategy. By default, this
# is also the name of the strategy, but the `:strategy` key can be given
# to customize this behavior
# @param [Hash] options The list of options
#
def define(name, **options, &block)
validate_options!(options)
name = name.to_sym
strategy = options[:strategy] || name
@__defined_pushes[name] ||= []
@__defined_pushes[name] << [strategy.to_sym, block]
end
# The String representation of this Push.
#
# @return [String]
def to_s
"Push"
end
# Custom merge method
def merge(other)
super.tap do |result|
other_pushes = other.instance_variable_get(:@__defined_pushes)
new_pushes = @__defined_pushes.dup
other_pushes.each do |key, tuples|
new_pushes[key] ||= []
new_pushes[key] += tuples
end
result.instance_variable_set(:@__defined_pushes, new_pushes)
end
end
# This returns the list of pushes defined in the Vagrantfile.
#
# @return [Array<Symbol>]
def defined_pushes
raise "Must finalize first!" if !@__finalized
@__defined_pushes.keys
end
# This returns the compiled push-specific configuration for the given
# provider.
#
# @param [#to_sym] name Name of the push
def get_push(name)
raise "Must finalize first!" if !@__finalized
@__defined_pushes[name.to_sym]
end
private
def validate_options!(options)
extra_keys = VALID_OPTIONS - options.keys
if !extra_keys.empty?
raise "Invalid option(s): #{extra_keys.join(", ")}"
end
end
end
end
end

View File

@ -25,6 +25,11 @@ module VagrantPlugins
PackageConfig PackageConfig
end end
config("push") do
require File.expand_path("../config/push", __FILE__)
PushConfig
end
config("vagrant") do config("vagrant") do
require File.expand_path("../config/vagrant", __FILE__) require File.expand_path("../config/vagrant", __FILE__)
VagrantConfig VagrantConfig

View File

@ -955,12 +955,19 @@ en:
end end
push_strategy_not_defined: |- push_strategy_not_defined: |-
The push strategy '%{name}' is not defined in the Vagrantfile. Defined The push strategy '%{name}' is not defined in the Vagrantfile. Defined
strategies are: strategy names are:
%{pushes}
push_strategy_not_defined: |-
There are no push strategies named '%{name}'. Please make sure you
spelled it correctly. If you are using an external push strategy, you
may need to install a plugin. Loaded push strategies are:
%{pushes} %{pushes}
push_strategy_not_provided: |- push_strategy_not_provided: |-
The Vagrantfile defines more than one 'push' strategy. Please specify a The Vagrantfile defines more than one 'push' strategy. Please specify a
strategy. Defined strategies are: strategy. Defined strategy names are:
%{pushes} %{pushes}
package_include_symlink: |- package_include_symlink: |-

View File

@ -6,14 +6,6 @@ describe VagrantPlugins::CommandPush::Command do
include_context "unit" include_context "unit"
include_context "command plugin helpers" include_context "command plugin helpers"
def create_registry(items={})
Vagrant::Registry.new.tap do |registry|
items.each do |k,v|
registry.register(k) { v }
end
end
end
let(:env) do let(:env) do
isolated_environment.tap do |env| isolated_environment.tap do |env|
env.vagrantfile("") env.vagrantfile("")
@ -22,7 +14,7 @@ describe VagrantPlugins::CommandPush::Command do
end end
let(:argv) { [] } let(:argv) { [] }
let(:pushes) { create_registry } let(:pushes) { {} }
subject { described_class.new(argv, env) } subject { described_class.new(argv, env) }
@ -50,7 +42,7 @@ describe VagrantPlugins::CommandPush::Command do
describe "#validate_pushes!" do describe "#validate_pushes!" do
context "when there are no pushes defined" do context "when there are no pushes defined" do
let(:pushes) { create_registry } let(:pushes) { {} }
context "when a strategy is given" do context "when a strategy is given" do
it "raises an exception" do it "raises an exception" do
@ -69,7 +61,7 @@ describe VagrantPlugins::CommandPush::Command do
context "when there is one push defined" do context "when there is one push defined" do
let(:noop) { double("noop") } let(:noop) { double("noop") }
let(:pushes) { create_registry(noop: noop) } let(:pushes) { { noop: noop } }
context "when a strategy is given" do context "when a strategy is given" do
context "when that strategy is not defined" do context "when that strategy is not defined" do
@ -98,7 +90,7 @@ describe VagrantPlugins::CommandPush::Command do
context "when there are multiple pushes defined" do context "when there are multiple pushes defined" do
let(:noop) { double("noop") } let(:noop) { double("noop") }
let(:ftp) { double("ftp") } let(:ftp) { double("ftp") }
let(:pushes) { create_registry(noop: noop, ftp: ftp) } let(:pushes) { { noop: noop, ftp: ftp } }
context "when a strategy is given" do context "when a strategy is given" do
context "when that strategy is not defined" do context "when that strategy is not defined" do