Highline Wrapper
A little wrapper to help ask some easy questions via the command-line with Highline. The types of questions this wrapper supports is:
- Open-ended question
- Yes/No question
- Multiple choice question where the user is allowed to select one answer
- Multiple choice "checkbox" question where the user is allowed to select multiple answers
Installation
Add this line to your application's Gemfile:
gem 'highline_wrapper'And then execute:
bundle installOr install it yourself as:
gem install highline_wrapperUsage
Once this gem is installed, you can then initiate a new HighlineWrapper object:
HighlineWrapper.newThen, add this to the top of your file (or to your gem):
require 'highline_wrapper'Then, you can call its questions to receive answers. There's several configuration options for each type of question. Look below for the different options for each type of question, and what they each return.
Open-ended questions
Question configuration options:
-
default: defaults to'' -
indicate_default_message: defaults totrue -
required: defaults tofalse -
secret: defaults tofalse
Notes:
- If
defaultis''andrequiredisfalse, and the user skips the question, the answer will be'' - If
indicate_default_messageistrue, then the wrapper will tell us what the default value returned is if the user skips the question- If
secretistrue, then the wrapper may automatically add a newline after a skipped answer... this is automatic from HighLine and is, unfortunately, out of the wrapper's control
- If
- If
requiredistrue, the question will repeat until the user answers the question - If
requiredistrue, then thedefaultvalue will be ignored (defaults to'', but could be set to whatever and the code won't care... the question is required) - If
secretistrue, then the command-line will hide the user's answer behind*
> HighlineWrapper.new.ask('What is your favorite number?')
What is your favorite number?
four
=> "four"
> HighlineWrapper.new.ask('What is your favorite number?', {required: true})
What is your favorite number?
--- This question is required ---
What is your favorite number?
--- This question is required ---
What is your favorite number?
--- This question is required ---
What is your favorite number?
2
=> "2"
> HighlineWrapper.new.ask('What is your favorite number?', {required: true, indicate_default_message: false})
What is your favorite number?
--- This question is required ---
What is your favorite number?
--- This question is required ---
What is your favorite number?
5
=> "5"
> HighlineWrapper.new.ask('What is your favorite number?', {indicate_default_message: false})
What is your favorite number?
=> ""
> HighlineWrapper.new.ask('What is your favorite color?')
What is your favorite color?
--- Default selected: EMPTY ---
=> ""
> HighlineWrapper.new.ask('What is your favorite color?', {default: 'orange'})
What is your favorite color?
--- Default selected: orange ---
=> "orange"
> HighlineWrapper.new.ask('Please type your private token:', {secret: true})
Please type your private token?
****************
=> "MY-PRIVATE-TOKEN"
> HighlineWrapper.new.ask('Please type your private token:', {secret: true, indicate_default_message: false})
Please type your private token:
=> ""
> HighlineWrapper.new.ask('Please type your private token:', {secret: true, required: true})
Please type your private token:
--- This question is required ---
Please type your private token:
--- This question is required ---
Please type your private token:
****************
=> "MY-PRIVATE-TOKEN"
> HighlineWrapper.new.ask('Please type your private token:', {secret: true})
Please type your private token:
--- Default selected: HIDDEN ---
=> ""Yes/No questions
Question configuration options:
-
default: defaults totrue(aka 'yes') -
indicate_default_message: defaults totrue -
required: defaults tofalse
Notes:
- If
defaultistrueandrequiredisfalse, and the user skips the question, the answer will betrue - If
indicate_default_messageistrue, then the wrapper will tell us what the default value returned is if the user skips the question - If
requiredistrue, the question will repeat until the user answers the question - If
requiredistrue, then thedefaultvalue will be ignored (defaults totrue, but could be set to whatever and the code won't care... the question is required) - The response to the question MUST be given either as
y/n/yes/noor with any capitalization... anything else given as a response will be unparseable
> HighlineWrapper.new.ask_yes_no('Do you like Ruby?')
Do you like Ruby?
--- Default selected: YES ---
=> true
> HighlineWrapper.new.ask_yes_no('Do you like Ruby?', {indicate_default_message: false})
Do you like Ruby?
=> true
> HighlineWrapper.new.ask_yes_no('Do you like Ruby?')
Do you like Ruby?
no
=> false
> HighlineWrapper.new.ask_yes_no('Do you like Ruby?', {default: false})
Do you like Ruby?
--- Default selected: NO ---
=> false
> HighlineWrapper.new.ask_yes_no('Do you like Ruby?', {required: true})
Do you like Ruby?
--- This question is required ---
Do you like Ruby?
--- This question is required ---
Do you like Ruby?
--- This question is required ---
Do you like Ruby?
N
=> false
> HighlineWrapper.new.ask_yes_no('Do you like Ruby?')
Do you like Ruby?
uh-huh
--- This question is required ---
Do you like Ruby?
YES
=> true
> HighlineWrapper.new.ask_yes_no('Do you like Ruby?')
Do you like Ruby?
yep
--- This question is required ---
Do you like Ruby?
yes
=> trueMultiple choice questions
Question configuration options:
-
default: defaults tonil -
indicate_default_message: defaults totrue -
required: defaults tofalse -
with_index: defaults tofalse(particularly handy when there may be duplicate-named but different items in the list—think Sally with ID 45 and Sally with ID 72)
Notes:
- If
defaultisnilandrequiredisfalse, and the user skips the question, the answer will benil - If
indicate_default_messageistrue, then the wrapper will tell us what the default value returned is if the user skips the question - If
requiredistrue, the question will repeat until the user answers the question - If
requiredistrue, then thedefaultvalue will be ignored (defaults tonil, but could be set to whatever and the code won't care... the question is required) - If
with_indexistrue, a hash will be returned with the choice AND the index of the selection in the originalchoicesarray- e.g.
{ value: 'c', index: 2 }
- e.g.
- If
with_indexisfalse, then a hash of one item will be returned- e.g.
{ value: 'c' }
- e.g.
> HighlineWrapper.new.ask_multiple_choice('What is your favorite number of these?', ['one', 'two', 'three'])
What is your favorite number of these?
1. one
2. two
3. three
2
=> {:value=>"two"}
> HighlineWrapper.new.ask_multiple_choice('What is your favorite number of these?', ['one', 'two', 'three'], {with_index: true})
What is your favorite number of these?
1. one
2. two
3. three
2
=> {:value=>"two", :index=>1}
> HighlineWrapper.new.ask_multiple_choice('What is your favorite number of these?', ['one', 'two', 'three'], {default: 'three', required: true, indicate_default_message: false})
What is your favorite number of these?
1. one
2. two
3. three
--- This question is required ---
What is your favorite number of these?
1. one
2. two
3. three
--- This question is required ---
What is your favorite number of these?
1. one
2. two
3. three
2
=> {:value=>"two"}
> HighlineWrapper.new.ask_multiple_choice('What is your favorite number of these?', ['one', 'two', 'three'], {with_index: true, default: 'one'})
What is your favorite number of these?
1. one
2. two
3. three
--- Default selected: 1. one ---
=> {:value=>"one", :index=>0}
> HighlineWrapper.new.ask_multiple_choice('What is your favorite number of these?', ['one', 'two', 'three'], {with_index: true, default: 'one', indicate_default_message: false})
What is your favorite number of these?
1. one
2. two
3. three
=> {:value=>"one", :index=>0}
> HighlineWrapper.new.ask_multiple_choice('What is your favorite number of these?', ['one', 'two', 'three'], {default: 'three', required: true})
What is your favorite number of these?
1. one
2. two
3. three
--- This question is required ---
What is your favorite number of these?
1. one
2. two
3. three
--- This question is required ---
What is your favorite number of these?
1. one
2. two
3. three
1
=> {:value=>"one"}
> HighlineWrapper.new.ask_multiple_choice('What is your favorite number of these?', ['one', 'two', 'three'], {default: nil})
What is your favorite number of these?
1. one
2. two
3. three
--- Default selected: EMPTY ---
=> nil
> HighlineWrapper.new.ask_multiple_choice('What is your favorite number of these?', ['one', 'two', 'three'], {default: nil, with_index: true})
What is your favorite number of these?
1. one
2. two
3. three
--- Default selected: EMPTY ---
=> nil
> HighlineWrapper.new.ask_multiple_choice('What is your favorite number of these?', ['one', 'two', 'three'], {default: nil, with_index: true, indicate_default_message: false})
What is your favorite number of these?
1. one
2. two
3. three
=> nilMultiple choice "checkbox" questions
Question configuration options:
-
defaults: defaults to[] -
indicate_default_message: defaults totrue -
required: defaults tofalse -
with_indexes: defaults tofalse(particularly handy when there may be duplicate-named but different items in the list—think Sally with ID 45 and Sally with ID 72)
Notes:
- If
defaultsis[]andrequiredisfalse, then the method will return an empty array - If
indicate_default_messageistrue, then the wrapper will tell us what the default value returned is if the user skips the question - If
requiredistrue, the question will repeat until the user answers the question - If
requiredistrue, then thedefaultsvalue will be ignored (this value is defaulting to[], but could be set to whatever and the code won't care... the question is required) - If
with_indexesistrue, an array of hashes will be returned with the choice AND the index (of the selection in the originalchoicesarray) in each hash- e.g.
[{ value: 'a', index: 0 }, { value: 'c', index: 2 }]
- e.g.
- If
with_indexesisfalse, then an hashes will be returned where each hash only has a value- e.g.
[{ value: 'a' }, { value: 'c' }]
- e.g.
> HighlineWrapper.new.ask_checkbox("What are your favorite numbers of these?", ['one', 'two','three'])
What are your favorite numbers of these?
1. one
2. two
3. three
1, 3
=> [{:value=>"one"}, {:value=>"three"}]
> HighlineWrapper.new.ask_checkbox("What are your favorite numbers of these?", ['one', 'two','three'], {with_indexes: true})
What are your favorite numbers of these?
1. one
2. two
3. three
1, 3
=> [{:value=>"one", :index=>0}, {:value=>"three", :index=>2}]
> HighlineWrapper.new.ask_checkbox("What are your favorite numbers of these?", ['one', 'two','three'], {with_indexes: true, indicate_default_message: false})
What are your favorite numbers of these?
1. one
2. two
3. three
=> []
> HighlineWrapper.new.ask_checkbox("What are your favorite numbers of these?", ['one', 'two','three'], {with_indexes: true})
What are your favorite numbers of these?
1. one
2. two
3. three
--- Defaults selected: EMPTY ---
=> []
> HighlineWrapper.new.ask_checkbox("What are your favorite numbers of these?", ['one', 'two','three'], {defaults: ['two', 'three']})
What are your favorite numbers of these?
1. one
2. two
3. three
--- Defaults selected: 2. two, 3. three ---
=> [{:value=>"two"}, {:value=>"three"}]
> HighlineWrapper.new.ask_checkbox("What are your favorite numbers of these?", ['one', 'two','three'], {required: true, with_indexes: true})
What are your favorite numbers of these?
1. one
2. two
3. three
--- This question is required ---
What are your favorite numbers of these?
1. one
2. two
3. three
--- This question is required ---
What are your favorite numbers of these?
1. one
2. two
3. three
2
=> [{:value=>"two", :index=>1}]
> HighlineWrapper.new.ask_checkbox("What are your favorite numbers of these?", ['one', 'two','three'], {required: true, with_indexes: false})
What are your favorite numbers of these?
1. one
2. two
3. three
--- This question is required ---
What are your favorite numbers of these?
1. one
2. two
3. three
1
=> [{:value=>"one"}]
> HighlineWrapper.new.ask_checkbox("What are your favorite numbers of these?", ['one', 'two','three'], {defaults: ['two', 'three'], with_indexes: true, indicate_default_message: false})
What are your favorite numbers of these?
1. one
2. two
3. three
=> [{:value=>"two", :index=>1}, {:value=>"three", :index=>2}]Tests
To run the tests, run bundle exec rspec from the command-line. GitHub Actions will also run the tests upon every commit to make sure they're up to date and that everything is working correctly. Locally, you can also run bundle exec guard to automatically run tests as you develop!
Contributing
To submit a feature request, bug ticket, etc, please submit an official GitHub issue. To copy or make changes, please fork this repository. When/if you'd like to contribute back to this upstream, please create a pull request on this repository.
Please follow included Issue Template(s) and Pull Request Template(s) when creating issues or pull requests.
Security Policy
To report any security vulnerabilities, please view this repository's Security Policy.
Licensing
For information on licensing, please see LICENSE.md.
Code of Conduct
When interacting with this repository, please follow Contributor Covenant's Code of Conduct.
Releasing
To make a new release of this gem:
- Merge the pull request via the big green button
- Run
git tag vX.X.Xandgit push --tag - Make a new release here
- Run
gem build *.gemspec - Run
gem push *.gemto push the new gem to RubyGems - Run
rm *.gemto clean up your local repository
To set up your local machine to push to RubyGems via the API, see the RubyGems documentation.