core: re-ask if confirmation bad input [GH-3027]

This commit is contained in:
Mitchell Hashimoto 2014-02-26 08:01:08 -08:00
parent dfee3f8445
commit 5f1caf3ada
4 changed files with 31 additions and 4 deletions

View File

@ -37,6 +37,7 @@ IMPROVEMENTS:
- core: Added "error-exit" type to machine-readable output which contains - core: Added "error-exit" type to machine-readable output which contains
error information that caused a non-zero exit status. [GH-2999] error information that caused a non-zero exit status. [GH-2999]
- command/destroy: confirmation will re-ask question if bad input. [GH-3027]
- guests/solaris: More accurate Solaris >= 11, < 11 detection. [GH-2824] - guests/solaris: More accurate Solaris >= 11, < 11 detection. [GH-2824]
- provisioners/chef-solo: New config `synced_folder_type` replaces the - provisioners/chef-solo: New config `synced_folder_type` replaces the
`nfs` option. This can be used to set the synced folders the provisioner `nfs` option. This can be used to set the synced folders the provisioner

View File

@ -11,10 +11,11 @@ module Vagrant
# @param [String] message The message to ask the user. # @param [String] message The message to ask the user.
# @param [Symbol] force_key The key that if present and true in # @param [Symbol] force_key The key that if present and true in
# the environment hash will skip the confirmation question. # the environment hash will skip the confirmation question.
def initialize(app, env, message, force_key=nil) def initialize(app, env, message, force_key=nil, **opts)
@app = app @app = app
@message = message @message = message
@force_key = force_key @force_key = force_key
@allowed = opts[:allowed]
end end
def call(env) def call(env)
@ -24,8 +25,16 @@ module Vagrant
# the result to "Y" # the result to "Y"
choice = "Y" if @force_key && env[@force_key] choice = "Y" if @force_key && env[@force_key]
# If we haven't chosen yes, then ask the user via TTY if !choice
choice = env[:ui].ask(@message) if !choice while true
# If we haven't chosen yes, then ask the user via TTY
choice = env[:ui].ask(@message)
# If we don't have an allowed set just exit
break if !@allowed
break if @allowed.include?(choice)
end
end
# The result is only true if the user said "Y" # The result is only true if the user said "Y"
env[:result] = choice && choice.upcase == "Y" env[:result] = choice && choice.upcase == "Y"

View File

@ -13,7 +13,7 @@ module Vagrant
message = I18n.t("vagrant.commands.destroy.confirmation", message = I18n.t("vagrant.commands.destroy.confirmation",
:name => env[:machine].name) :name => env[:machine].name)
super(app, env, message, force_key) super(app, env, message, force_key, allowed: ["y", "n", "Y", "N"])
end end
end end
end end

View File

@ -33,4 +33,21 @@ describe Vagrant::Action::Builtin::Confirm do
described_class.new(app, env, message).call(env) described_class.new(app, env, message).call(env)
env[:result].should_not be env[:result].should_not be
end end
it "should ask multiple times if an allowed set is given and response isn't in that set" do
times = 0
env[:ui].stub(:ask) do |arg|
expect(arg).to eql(message)
times += 1
if times <= 3
"nope"
else
"y"
end
end
described_class.new(app, env, message, allowed: ["y", "N"]).call(env)
expect(env[:result]).to be_true
expect(times).to eq(4)
end
end end