From eb3ceb24dc7bdb08498c755b3a37001c5d74b2e9 Mon Sep 17 00:00:00 2001 From: Van Miranda Date: Wed, 22 May 2013 19:08:33 -0700 Subject: [PATCH 1/2] Shell#ask: support a noecho option for stdin --- lib/thor/shell/basic.rb | 8 +++++++- spec/shell/basic_spec.rb | 5 +++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/thor/shell/basic.rb b/lib/thor/shell/basic.rb index d9119caef..c6c3d45ad 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 @@ -381,7 +382,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[:noecho] + 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..f79476f24 100644 --- a/spec/shell/basic_spec.rb +++ b/spec/shell/basic_spec.rb @@ -29,6 +29,11 @@ def shell expect(shell.ask("")).to eq(nil) end + it "prints a message to the user and does not echo stdin if the noecho option is set to true" do + $stdout.should_receive(:print).with('What\'s your password? ') + $stdin.should_receive(:noecho).and_return('mysecretpass') + expect(shell.ask("What's your password?", :noecho => true)).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] ') From dbfdd30f53f0cd911c462d500071c92f25271610 Mon Sep 17 00:00:00 2001 From: Van Miranda Date: Sat, 1 Jun 2013 11:53:43 -0700 Subject: [PATCH 2/2] Update Ask documentation and change API to be :echo => false --- lib/thor/shell/basic.rb | 7 ++++++- spec/shell/basic_spec.rb | 5 +++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/thor/shell/basic.rb b/lib/thor/shell/basic.rb index c6c3d45ad..1c15ae642 100644 --- a/lib/thor/shell/basic.rb +++ b/lib/thor/shell/basic.rb @@ -41,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 @@ -383,7 +388,7 @@ def ask_simply(statement, color, options) message = [statement, ("(#{default})" if default), nil].uniq.join(" ") say(message, color) - result = if options[:noecho] + result = if options[:echo] == false stdin.noecho(&:gets) else stdin.gets diff --git a/spec/shell/basic_spec.rb b/spec/shell/basic_spec.rb index f79476f24..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,10 +30,10 @@ def shell expect(shell.ask("")).to eq(nil) end - it "prints a message to the user and does not echo stdin if the noecho option is set to true" do + 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?", :noecho => true)).to eq("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