diff --git a/lib/thor/shell/basic.rb b/lib/thor/shell/basic.rb index d9119caef..1c15ae642 100644 --- a/lib/thor/shell/basic.rb +++ b/lib/thor/shell/basic.rb @@ -1,4 +1,5 @@ require 'tempfile' +require 'io/console' class Thor module Shell @@ -40,11 +41,16 @@ def padding=(value) # they will be shown a message stating that one of those answers # must be given and re-asked the question. # + # If asking for sensitive information, the :echo option can be set + # to false to mask user input from $stdin. + # # ==== Example # ask("What is your name?") # # ask("What is your favorite Neopolitan flavor?", :limited_to => ["strawberry", "chocolate", "vanilla"]) # + # ask("What is your password?", :echo => false) + # def ask(statement, *args) options = args.last.is_a?(Hash) ? args.pop : {} color = args.first @@ -381,7 +387,12 @@ def ask_simply(statement, color, options) default = options[:default] message = [statement, ("(#{default})" if default), nil].uniq.join(" ") say(message, color) - result = stdin.gets + + result = if options[:echo] == false + stdin.noecho(&:gets) + else + stdin.gets + end return unless result diff --git a/spec/shell/basic_spec.rb b/spec/shell/basic_spec.rb index fd45d053f..9d0e1b726 100644 --- a/spec/shell/basic_spec.rb +++ b/spec/shell/basic_spec.rb @@ -20,6 +20,7 @@ def shell it "prints a message to the user and gets the response" do $stdout.should_receive(:print).with("Should I overwrite it? ") $stdin.should_receive(:gets).and_return('Sure') + $stdin.should_not_receive(:noecho).and_return('Sure') expect(shell.ask("Should I overwrite it?")).to eq("Sure") end @@ -29,6 +30,11 @@ def shell expect(shell.ask("")).to eq(nil) end + it "prints a message to the user and does not echo stdin if the echo option is set to false" do + $stdout.should_receive(:print).with('What\'s your password? ') + $stdin.should_receive(:noecho).and_return('mysecretpass') + expect(shell.ask("What's your password?", :echo => false)).to eq("mysecretpass") + end it "prints a message to the user with the available options and determines the correctness of the answer" do $stdout.should_receive(:print).with('What\'s your favorite Neopolitan flavor? [strawberry, chocolate, vanilla] ')