diff --git a/lib/vagrant/environment.rb b/lib/vagrant/environment.rb index 82cab0411..acda0c178 100644 --- a/lib/vagrant/environment.rb +++ b/lib/vagrant/environment.rb @@ -571,7 +571,7 @@ module Vagrant # # @return [Array] def pushes - vagrantfile.config.push.__compiled_pushes.keys + self.vagrantfile.config.push.__compiled_pushes.keys end # This returns a machine with the proper provider for this environment. diff --git a/plugins/commands/push/command.rb b/plugins/commands/push/command.rb index 398e4e279..f3390723b 100644 --- a/plugins/commands/push/command.rb +++ b/plugins/commands/push/command.rb @@ -7,56 +7,73 @@ module VagrantPlugins "deploys code in this environment to a configured destination" end - # @todo support multiple strategies if requested by the community def execute + options = { all: false } opts = OptionParser.new do |o| o.banner = "Usage: vagrant push [strategy] [options]" + o.on("-a", "--all", "Run all defined push strategies") do + options[:all] = true + end end # Parse the options argv = parse_options(opts) return if !argv - name = argv[0] - pushes = @env.pushes + names = validate_pushes!(@env.pushes, argv, options) - validate_pushes!(pushes, name) - - @logger.debug("'push' environment with strategy: `#{name}'") - @env.push(name) + names.each do |name| + @logger.debug("'push' environment with strategy: `#{name}'") + @env.push(name) + end 0 end - # Validate that the given list of pushes and strategy are valid. + # Validate that the given list of names corresponds to valid pushes. # - # @raise [PushesNotDefined] if there are no pushes defined for the - # environment - # @raise [PushStrategyNotDefined] if a strategy is given, but does not - # correspond to one that exists in the environment + # @raise Vagrant::Errors::PushesNotDefined + # if there are no pushes defined + # @raise Vagrant::Errors::PushStrategyNotProvided + # if there are multiple push strategies defined and none were specified + # and `--all` was not given + # @raise Vagrant::Errors::PushStrategyNotDefined + # if any of the given push names do not correspond to a push strategy # - # @param [Registry] pushes The list of pushes as a {Registry} - # @param [#to_sym, nil] name The name of the strategy + # @param [Array] pushes + # the list of pushes defined by the environment + # @param [Array] names + # the list of names provided by the user on the command line + # @param [Hash] options + # a list of options to pass to the validation # - # @return [true] - def validate_pushes!(pushes, name=nil) + # @return [Array] + # the compiled list of pushes + # + def validate_pushes!(pushes, names = [], options = {}) if pushes.nil? || pushes.empty? raise Vagrant::Errors::PushesNotDefined end - if name.nil? - if pushes.length != 1 + names = Array(names).flatten.compact.map(&:to_sym) + + if names.empty? || options[:all] + if options[:all] || pushes.length == 1 + return pushes.map(&:to_sym) + else raise Vagrant::Errors::PushStrategyNotProvided, pushes: pushes end - else - if !pushes.include?(name.to_sym) + end + + names.each do |name| + if !pushes.include?(name) raise Vagrant::Errors::PushStrategyNotDefined, name: name, pushes: pushes end end - true + return names end end end diff --git a/test/unit/plugins/commands/push/command_test.rb b/test/unit/plugins/commands/push/command_test.rb index 18998e87a..292e2ee0e 100644 --- a/test/unit/plugins/commands/push/command_test.rb +++ b/test/unit/plugins/commands/push/command_test.rb @@ -25,15 +25,35 @@ describe VagrantPlugins::CommandPush::Command do describe "#execute" do before do allow(subject).to receive(:validate_pushes!) + .and_return([:noop]) allow(env).to receive(:pushes) allow(env).to receive(:push) end it "validates the pushes" do - expect(subject).to receive(:validate_pushes!).once + expect(subject).to receive(:validate_pushes!) + .with(nil, argv, kind_of(Hash)) + .once subject.execute end + it "parses arguments" do + list = ["noop", "ftp"] + instance = described_class.new(list, env) + expect(instance).to receive(:validate_pushes!) + .with(nil, list, kind_of(Hash)) + .and_return([]) + instance.execute + end + + it "parses options" do + instance = described_class.new(["--all"], env) + expect(instance).to receive(:validate_pushes!) + .with(nil, argv, all: true) + .and_return([]) + instance.execute + end + it "delegates to Environment#push" do expect(env).to receive(:push).once subject.execute @@ -72,17 +92,22 @@ describe VagrantPlugins::CommandPush::Command do end context "when that strategy is defined" do - it "does not raise an exception" do - expect { subject.validate_pushes!(pushes, :noop) } - .to_not raise_error + it "returns that push" do + expect(subject.validate_pushes!(pushes, :noop)).to eq([:noop]) end end end context "when no strategy is given" do - it "does not raise an exception" do - expect { subject.validate_pushes!(pushes) } - .to_not raise_error + it "returns the push" do + expect(subject.validate_pushes!(pushes)).to eq([:noop]) + end + end + + context "when --all is given" do + it "returns the push" do + expect(subject.validate_pushes!(pushes, [], all: true)) + .to eq([:noop]) end end end @@ -101,21 +126,33 @@ describe VagrantPlugins::CommandPush::Command do end context "when that strategy is defined" do - it "does not raise an exception" do - expect { subject.validate_pushes!(pushes, :noop) } - .to_not raise_error - expect { subject.validate_pushes!(pushes, :ftp) } - .to_not raise_error + it "returns the strategy" do + expect(subject.validate_pushes!(pushes, :noop)).to eq([:noop]) + expect(subject.validate_pushes!(pushes, :ftp)).to eq([:ftp]) end end end + context "when multiple strategies are given" do + it "returns the pushes" do + expect(subject.validate_pushes!(pushes, [:noop, :ftp])) + .to eq([:noop, :ftp]) + end + end + context "when no strategy is given" do it "raises an exception" do expect { subject.validate_pushes!(pushes) } .to raise_error(Vagrant::Errors::PushStrategyNotProvided) end end + + context "when --all is given" do + it "returns the pushes" do + expect(subject.validate_pushes!(pushes, [], all: true)) + .to eq([:noop, :ftp]) + end + end end end end diff --git a/website/docs/source/v2/push/index.html.md b/website/docs/source/v2/push/index.html.md index 310039176..5f061862a 100644 --- a/website/docs/source/v2/push/index.html.md +++ b/website/docs/source/v2/push/index.html.md @@ -52,6 +52,16 @@ subcommand: $ vagrant push staging ``` +Pushes will be run in the order you specify on the command line, **not the order +they are specified in the `Vagrantfile`!** + +To execute all the Vagrant Push strategies, specify the `--all` flag with no +other arguments: + +```shell +$ vagrant push --all +``` + Vagrant Push is the easiest way to deploy your application. You can read more in the documentation links on the sidebar.