Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added some new features #591

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 52 additions & 4 deletions lib/thor/shell/basic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def indent(count = 1)
# Asks something to the user and receives a response.
#
# If asked to limit the correct responses, you can pass in an
# array of acceptable answers. If one of those is not supplied,
# array or range of acceptable answers. If one of those is not supplied,
# they will be shown a message stating that one of those answers
# must be given and re-asked the question.
#
Expand All @@ -74,12 +74,48 @@ def ask(statement, *args)
color = args.first

if options[:limited_to]
ask_filtered(statement, color, options)
if options[:limited_to].is_a?(Range)
ask_range(statement, color, options)
else
ask_filtered(statement, color, options)
end
else
ask_simply(statement, color, options)
end
end

# Asks something to the user and receives a response, but only if the
# provided value is nil.
#
# If asked to limit the correct responses, you can pass in an
# array or range of acceptable answers. If one of those is not supplied,
# 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.
#
# If the required input is a path, then set the path option to
# true. This will enable tab completion for file paths relative
# to the current working directory on systems that support
# Readline.
#
# ==== Example
# ask("What is your name?")
#
# ask("What is your favorite Neopolitan flavor?", :limited_to => ["strawberry", "chocolate", "vanilla"])
#
# ask("How old are you?", :limited_to => (1...120))
#
# ask("What is your password?", :echo => false)
#
# ask("Where should the file be saved?", :path => true)
#
def ask_if_nil(value, statement, *args)
return value unless value.nil?
ask(statement, args)
end

# Say (print) something to the user. If the sentence ends with a whitespace
# or tab character, a new line is not appended (print + flush). Otherwise
# are passed straight to puts (behavior got from Highline).
Expand Down Expand Up @@ -423,9 +459,21 @@ def ask_simply(statement, color, options)
end
end

def ask_range(statement, color, options)
answer_set = options[:limited_to].to_a
correct_answer = nil
until correct_answer
answers = "#{answer_set.min}-#{answer_set.max}"
answer = ask_simply("#{statement} [#{answers}]", color, options)
correct_answer = answer_set.map{ |a| a.to_s }.include?(answer) ? answer : nil
say("Your response must be in the range: [#{answers}]. Please try again.") unless correct_answer
end
correct_answer
end

def ask_filtered(statement, color, options)
answer_set = options[:limited_to]
correct_answer = nil
answer_set = options[:limited_to]
correct_answer = nil
until correct_answer
answers = answer_set.join(", ")
answer = ask_simply("#{statement} [#{answers}]", color, options)
Expand Down
38 changes: 28 additions & 10 deletions lib/thor/shell/color.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,44 @@ module Shell
#
class Color < Basic
# Embed in a String to clear all previous ANSI sequences.
CLEAR = "\e[0m"
CLEAR = "\e[0m"
# The start of an ANSI bold sequence.
BOLD = "\e[1m"
BOLD = "\e[1m"

# Set the terminal's foreground ANSI color to black.
BLACK = "\e[30m"
BLACK = "\e[30m"
# Set the terminal's foreground ANSI color to black.
BRIGHT_BLACK = "\e[30;1m"
# Set the terminal's foreground ANSI color to red.
RED = "\e[31m"
# Set the terminal's foreground ANSI color to red.
RED = "\e[31m"
BRIGHT_RED = "\e[31;1m"
# Set the terminal's foreground ANSI color to green.
GREEN = "\e[32m"
# Set the terminal's foreground ANSI color to green.
GREEN = "\e[32m"
BRIGHT_GREEN = "\e[32;1m"
# Set the terminal's foreground ANSI color to yellow.
YELLOW = "\e[33m"
YELLOW = "\e[33m"
# Set the terminal's foreground ANSI color to yellow.
BRIGHT_YELLOW = "\e[33;1m"
# Set the terminal's foreground ANSI color to blue.
BLUE = "\e[34m"
# Set the terminal's foreground ANSI color to blue.
BLUE = "\e[34m"
BRIGHT_BLUE = "\e[34;1m"
# Set the terminal's foreground ANSI color to magenta.
MAGENTA = "\e[35m"
MAGENTA = "\e[35m"
# Set the terminal's foreground ANSI color to magenta.
BRIGHT_MAGENTA = "\e[35;1m"
# Set the terminal's foreground ANSI color to cyan.
CYAN = "\e[36m"
# Set the terminal's foreground ANSI color to cyan.
CYAN = "\e[36m"
BRIGHT_CYAN = "\e[36;1m"
# Set the terminal's foreground ANSI color to white.
WHITE = "\e[37m"
# Set the terminal's foreground ANSI color to white.
WHITE = "\e[37m"
BRIGHT_WHITE = "\e[37;1m"



# Set the terminal's background ANSI color to black.
ON_BLACK = "\e[40m"
Expand Down
15 changes: 15 additions & 0 deletions spec/shell/basic_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ def shell
expect(shell.ask('What\'s your favorite Neopolitan flavor?', :limited_to => flavors)).to eq("chocolate")
end

it "prints a message to the user with the available range and reasks the question after an incorrect response" do
ages = (1..120)
expect($stdout).to receive(:print).with("Your response must be in the range: [1-120]. Please try again.\n")
expect(Thor::LineEditor).to receive(:readline).with('How old are you? [1-120] ', :limited_to => ages).and_return("150", "20")
expect(shell.ask('How old are you?', :limited_to => ages)).to eq("20")
end


it "prints a message to the user containing a default and sets the default if only enter is pressed" do
expect(Thor::LineEditor).to receive(:readline).with('What\'s your favorite Neopolitan flavor? (vanilla) ', :default => "vanilla").and_return("")
expect(shell.ask('What\'s your favorite Neopolitan flavor?', :default => "vanilla")).to eq("vanilla")
Expand All @@ -92,6 +100,13 @@ def shell
expect(Thor::LineEditor).to receive(:readline).with('What\'s your favorite Neopolitan flavor? [strawberry, chocolate, vanilla] (vanilla) ', :default => "vanilla", :limited_to => flavors).and_return("moose tracks", "")
expect(shell.ask("What's your favorite Neopolitan flavor?", :default => "vanilla", :limited_to => flavors)).to eq("vanilla")
end

it "prints a message to the user with the available range and reasks the question after an incorrect response and then returns the default" do
ages = (1..120)
expect($stdout).to receive(:print).with("Your response must be in the range: [1-120]. Please try again.\n")
expect(Thor::LineEditor).to receive(:readline).with('How old are you? [1-120] (20) ', :default => "20", :limited_to => ages).and_return("150", "")
expect(shell.ask("How old are you?", :default => "20", :limited_to => ages)).to eq("20")
end
end

describe "#yes?" do
Expand Down