README.md in cliutils-1.2.5 vs README.md in cliutils-1.2.6
- old
+ new
@@ -52,11 +52,11 @@
# Libraries
CLIUtils offers:
* [PrettyIO](#prettyio): nicer-looking CLI messages
-* [Messenging](#messenging): a full-featured Logger
+* [Messenging](#messenging): a system to display nicely-formatted messages to one or more tagets
* [Configuration](#configuration): a app configuration manager
* [Prefs](#prefs): a preferences prompter and manager
## PrettyIO
@@ -71,11 +71,11 @@
```ruby
puts 'A sample string'.red
```
![alt text](https://raw.githubusercontent.com/bachya/cli-utils/master/res/readme-images/prettyio-red-text.png "Colored Text via PrettyIO")
-PrettyIO gives you utility methods for the common ANSI color codes:
+You get a stable of utility methods for the common ANSI color codes:
```ruby
String.blue
String.cyan
String.green
@@ -93,11 +93,11 @@
![alt text](https://raw.githubusercontent.com/bachya/cli-utils/master/res/readme-images/prettyio-gnarly-text.png "Complex Colored Text via PrettyIO")
Naturally, memorizing the ANSI color scheme is a pain, so PrettyIO gives you a convenient method to look up these color combinations:
```ruby
-CLIUtils::PrettyIO.color_chart
+color_chart
```
![alt text](https://raw.githubusercontent.com/bachya/cli-utils/master/res/readme-images/prettyio-color-chart.png "PrettyIO Color Chart")
## Messenging
@@ -176,10 +176,11 @@
Often, it's desirable to log messages as they appear to your user. `messenging` makes this a breeze by allowing you to attach and detach Logger instances at will.
For instance, let's say you wanted to log a few messages to both your user's STDOUT and to `file.txt`:
```Ruby
+# By default, messenger only outputs to STDOUT.
messenger.info('This should only appear in STDOUT.')
# messenger.attach takes a Hash of string/symbol keys
# and Logger values (so you can refer to them later on).
messenger.attach(MY_FILE_LOGGER: Logger.new('file.txt'))
@@ -228,10 +229,11 @@
### Adding/Removing Sections
Sections are top levels of the configuration file and are managed via the `configurator` object:
```Ruby
+configuration.add_section(:app_data)
configuration.add_section(:user_data)
configuration.add_section(:program_data)
configuration.delete_section(:program_data)
```
@@ -255,26 +257,46 @@
Note that all your keys are converted to strings before saving (and, likewise, are converted to symbols, when loading). Assuming we used the commands above, we could expect this to be the contents of `~/.my-app-config`:
```YAML
---
+app_data:
user_data:
username: bob
```
### Checking Configuration Versions
-Often, you'll want to check the user's current version of your app against the last version that required some sort of configuration change. `configurator` allows for this via its `compare_version` method:
+Often, you'll want to check the user's current version of your app against the last version that required some sort of configuration change. `configurator` allows for this via its `compare_version` method.
+Assume you have a config file that looks like this:
+
+```YAML
+---
+app_data:
+ # The current version of the app
+ APP_VERSION: 1.0.0
+
+ # The last version that required
+ # a configuration change
+ NEWEST_CONFIG_VERSION: 1.8.0
+
+ # ...other keys...
+```
+
+...this will initiate a version check (and give you the option to do something with that information):
+
```Ruby
# Tell your configurator the name of the key that
# stores the app's version in its configuration file.
+# NOTE that you don't have to specify the section.
configuration.cur_version_key = :APP_VERSION
# Tell your configurator the name of the key that
# stores the last version that needed a configuration
# change.
+# NOTE that you don't have to specify the section.
configuration.last_version_key = :NEWEST_CONFIG_VERSION
# Run the check and use a block to get
# the current and "last-needing-changes"
# versions (and do something about it).
@@ -323,20 +345,77 @@
```Ruby
prefs = CLIUtils::Prefs.new('path/to/yaml/file')
```
+`Prefs` can also be instantiated via a Hash or an array of prompts; the overall schema remains the same:
+
+```Ruby
+# Instantiation through a Hash
+h = {
+ prompts: [
+ {
+ prompt: 'What is your name?',
+ default: 'Bob Cobb',
+ config_key: :name,
+ config_section: :personal_info
+ },
+ {
+ prompt: 'What is your age?',
+ default: '45',
+ config_key: :age,
+ config_section: :personal_info
+ },
+ {
+ prompt: 'Batman or Superman?',
+ default: 'Batman',
+ config_key: :superhero,
+ config_section: :personal_info
+ }
+ ]
+}
+
+prefs = CLIUtils::Prefs.new(h)
+
+# Instantiation through an Array
+
+a = [
+ {
+ prompt: 'What is your name?',
+ default: 'Bob Cobb',
+ config_key: :name,
+ config_section: :personal_info
+ },
+ {
+ prompt: 'What is your age?',
+ default: '45',
+ config_key: :age,
+ config_section: :personal_info
+ },
+ {
+ prompt: 'Batman or Superman?',
+ default: 'Batman',
+ config_key: :superhero,
+ config_section: :personal_info
+ }
+]
+
+prefs = CLIUtils::Prefs.new(a)
+```
+
+### Prompting the User
+
With valid preferences loaded, simply use `ask` to begin prompting your user:
```Ruby
prefs.ask
```
![alt text](https://raw.githubusercontent.com/bachya/cli-utils/master/res/readme-images/prefs-ask.png "Prefs.ask")
### Prerequisites
-Sometimes, you need to answer certain prompts before others become relevant. `Prefs` allows this via a `prereqs` key, which can contain multiple already-answered key/value pairs to check for. For instance, imagine we want to drill into a user's superhero preference a bit further:
+Sometimes, you need to answer certain prompts before others become relevant. `Prefs` allows this via a `prereqs` key, which can contain multiple already-answered key/value pairs to check for. For instance, imagine we want to drill into a user's superhero preference a bit further; using our previously-used YAML prefs file:
```YAML
prompts:
- prompt: Batman or Superman?
default: Batman
@@ -354,20 +433,28 @@
config_key: superman_answer
config_section: personal_info
prereqs:
- config_key: superhero
config_value: Superman
+ - prompt: Why don't you have a clue?
+ config_key: no_clue
+ config_section: personal_info
+ prereqs:
+ - config_key: superhero
+ config_value: Superman
+ - config_key: superman_answer
+ config_value: No clue
```
`prereqs` checks for already-answered preferences (based on a Configurator key and value); assuming everything checks out, the subsequent preferences are collected:
```Ruby
prefs.ask
```
![alt text](https://raw.githubusercontent.com/bachya/cli-utils/master/res/readme-images/prefs-ask-prereqs.png "Prerequisities")
-Be careful tht you don't define any circular prerequisities (e.g., A requires B and B requires A). In that case, neither preference will be collected.
+Be careful that you don't define any circular prerequisities (e.g., A requires B and B requires A). In that case, both preferences will be ignored by `Prefs.ask`.
### Options
What if you want to limit a preference to a certain set of options? Easy! Imagine we want to expand the previous example and force the user to choose either "Batman" or "Superman":
@@ -390,10 +477,18 @@
config_key: superman_answer
config_section: personal_info
prereqs:
- config_key: superhero
config_value: Superman
+ - prompt: Why don't you have a clue?
+ config_key: no_clue
+ config_section: personal_info
+ prereqs:
+ - config_key: superhero
+ config_value: Superman
+ - config_key: superman_answer
+ config_value: No clue
```
Once in place:
```Ruby
@@ -444,11 +539,11 @@
config_section: personal_info
behaviors:
- local_filepath
```
-The `local_filepath` behavior will expand the user's answer as a filepath (e.g., `~/.ssh` will get saved as `/Users/bachya/.ssh/`).
+The `local_filepath` behavior will expand the user's answer as a filepath (e.g., `~/.ssh` will get saved as `/Users/bob/.ssh/`).
`Prefs` currently supports these behaviors:
* `local_filepath`: runs File.expand_path on the answer
@@ -490,10 +585,10 @@
# Contributing
Contributions are welcome and encouraged. To contribute:
-1. Fork it ( http://github.com/bachya/cliutils/fork )
+1. Fork it (http://github.com/bachya/cliutils/fork)
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request