cli_helper 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +222 -11
- data/cli_helper.gemspec +17 -14
- data/example/cli_stub.rb +64 -11
- data/lib/cli_helper.rb +251 -277
- data/tests/README.txt +18 -0
- data/tests/cli_helper_test.rb +217 -0
- data/tests/config/sample.ini +6 -0
- data/tests/config/sample.ini.erb +9 -0
- data/tests/config/sample.rb +15 -0
- data/tests/config/sample.rb.erb +20 -0
- data/tests/config/sample.txt +12 -0
- data/tests/config/sample.txt.erb +16 -0
- data/tests/config/sample.xyzzy +1 -0
- data/tests/config/sample.yml +16 -0
- data/tests/config/sample.yml.erb +17 -0
- metadata +61 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2bf433b3f85f6369eda6ca70e7270c62ea73de64
|
4
|
+
data.tar.gz: 9c080c925aa6f8e106d2cd7055e8015cd9391bc4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4c1bf70ad6f53fd6c1a6578be150a8621c9588452cad240c233500a00aea0613fa7f4b428caf5c029fb806c5b9ba537f0c78e60aa58af727e1f83116915b65b
|
7
|
+
data.tar.gz: 86d255f5568ff8ce8ea8d1ce024f7ddf7eabb5d22f1e05cd7dfd8322de57edb241795c96ace9b20458c856ebfd8a08d6f7f4eadbece59b6b341df6a01904265f
|
data/README.md
CHANGED
@@ -1,22 +1,233 @@
|
|
1
|
-
# cli_helper
|
1
|
+
# cli_helper
|
2
|
+
|
3
|
+
If you write lots of command-line utility programs, or
|
4
|
+
even if you don't the cli_helper gem can be a helper
|
5
|
+
to you. It integrates several common gems to give
|
6
|
+
a comprehensive configuration management experience.
|
7
|
+
|
8
|
+
Here are the gems used and what they do:
|
9
|
+
|
10
|
+
* configatron
|
11
|
+
* makes config info available
|
12
|
+
* http://github.com/markbates/configatron
|
13
|
+
|
14
|
+
* nenv
|
15
|
+
* parses ENV for friendly use
|
16
|
+
* http://github.com/e2/nenv
|
17
|
+
|
18
|
+
* parseconfig
|
19
|
+
* parses INI files
|
20
|
+
* http://github.com/datafolklabs/ruby-parseconfig
|
21
|
+
|
22
|
+
* slop
|
23
|
+
* parses ARGV
|
24
|
+
* http://github.com/leejarvis/slop
|
25
|
+
|
26
|
+
|
27
|
+
## Convention
|
28
|
+
|
29
|
+
The convention w/r/t what value amoung concurrent sources
|
30
|
+
is the correct one to use is hierarchic
|
31
|
+
where the layer above trumps all the layers below. This is the order:
|
32
|
+
|
33
|
+
* command-line parameter
|
34
|
+
* config file value
|
35
|
+
* system environment variable
|
36
|
+
* default
|
37
|
+
|
38
|
+
This ordering says that regardless what you have set in
|
39
|
+
a config file or ENV or as a default, the value of the
|
40
|
+
command line parameter will be used.
|
41
|
+
|
42
|
+
I like to use ERB within my config files. Consider 'default.yml.erb'
|
43
|
+
below:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
---
|
47
|
+
host: <%= Nenv.host || 'localhost' %>
|
48
|
+
```
|
49
|
+
|
50
|
+
Processing this file will give me either the default value for host
|
51
|
+
of 'localhost' or if defined the value of the system environment
|
52
|
+
variable HOST. I like Nenv over ENV.
|
53
|
+
|
54
|
+
Now suppose I use cli_helper within a program and execute the
|
55
|
+
program like this:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
program.rb --host devhost --config default.yml.erb,prod.ini
|
59
|
+
```
|
60
|
+
|
61
|
+
Because I have specifically called out the value of host on the
|
62
|
+
command line, that value will trump anything that comes from the
|
63
|
+
config file.
|
64
|
+
|
65
|
+
Did you notice that I had two files specified with the --config option?
|
66
|
+
|
67
|
+
The config files are processed in the order that they are given on the command
|
68
|
+
line. Whatever values were obtained from the first file will be over-written
|
69
|
+
by the second and any subsequent config files. Regardless of their
|
70
|
+
values for host, the command-line value trumps them all.
|
71
|
+
|
72
|
+
|
73
|
+
## Config files
|
74
|
+
|
75
|
+
cli_helper supports multiple types of configuration files:
|
76
|
+
|
77
|
+
```text
|
78
|
+
*.rb
|
79
|
+
*.yml
|
80
|
+
*.yml.erb
|
81
|
+
*.ini
|
82
|
+
*.txt (in the INI format)
|
83
|
+
*.ini.erb -- not currently supported
|
84
|
+
*.txt.erb -- not currenly supported
|
85
|
+
```
|
86
|
+
|
87
|
+
All values obtained from config files and command line parameters are
|
88
|
+
held in the configatron structure.
|
89
|
+
|
90
|
+
|
91
|
+
## Common Command-line Options
|
92
|
+
|
93
|
+
cli_helper predefines common command-line options. These
|
94
|
+
can to disabled by the program if necessary. The common options
|
95
|
+
are:
|
96
|
+
|
97
|
+
```text
|
98
|
+
-h, --help
|
99
|
+
-d, --debug
|
100
|
+
-v, --verbose
|
101
|
+
--version
|
102
|
+
--config (optional)
|
103
|
+
```
|
104
|
+
|
105
|
+
To enable the support for config files do this before
|
106
|
+
calling the #cli_helger() method:
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
configatron.support_config_files = true
|
110
|
+
```
|
2
111
|
|
3
|
-
|
4
|
-
|
5
|
-
quick and dirty command-line based utilities. Mostly they are one-offs
|
6
|
-
but sometimes they hang around.
|
112
|
+
To disable any of the other common options do this before
|
113
|
+
involking cli_helper:
|
7
114
|
|
8
|
-
|
9
|
-
|
10
|
-
|
115
|
+
```ruby
|
116
|
+
configatron.disable_help = true
|
117
|
+
configatron.disable_debug = true
|
118
|
+
configatron.disable_verbose = true
|
119
|
+
cpnfogatrpm/dosab;e_version = true
|
120
|
+
```
|
121
|
+
|
122
|
+
## Other options
|
123
|
+
|
124
|
+
The default behavior is to raise an exception if an unspecified option is
|
125
|
+
used on the command line. For example if your program just uses the common
|
126
|
+
options and someone invokes the program with --xyzzy then an exception will be
|
127
|
+
raised saying that the option is unknown.
|
128
|
+
|
129
|
+
To prevent this exception you can set the suppress_errors parameter. With
|
130
|
+
this parameter set to true an unknown option will just be added to the unprocessed
|
131
|
+
arguments array.
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
configatron.suppress_errors = true
|
135
|
+
```
|
136
|
+
|
137
|
+
The unprocessed options can be access via the arguments array:
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
configatron.arguments
|
141
|
+
```
|
142
|
+
|
143
|
+
The arguments array is also where you will find anything else from the
|
144
|
+
command line that was not processed by the cli_helper. For example:
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
my_program.rb -v *.txt
|
148
|
+
```
|
149
|
+
|
150
|
+
The file names matching the '*.txt' glob will be put into the configatron.arguments
|
151
|
+
array.
|
152
|
+
|
153
|
+
|
154
|
+
## Boolean options auto-generate methods
|
155
|
+
|
156
|
+
Any boolean command-line option specified, even the predefined common ones,
|
157
|
+
have two methods defined: query(?) and banger(!). For the help options
|
158
|
+
the methods look like this:
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
def help?
|
162
|
+
configatron.help
|
163
|
+
end
|
164
|
+
|
165
|
+
def help!
|
166
|
+
configatron.help = true
|
167
|
+
end
|
168
|
+
```
|
169
|
+
|
170
|
+
## Names of command-line options
|
171
|
+
|
172
|
+
If you specify a command-line option of xyzzy, then an
|
173
|
+
entry in the configatron structure will be created having the
|
174
|
+
name 'xyzzy'. If you do not use a long-form for the option
|
175
|
+
the short option name will be used. For example '-x' will
|
176
|
+
be accessed as configatron.x
|
177
|
+
|
178
|
+
|
179
|
+
## Support methods
|
180
|
+
|
181
|
+
There are several support methods that I have included in cli_helper
|
182
|
+
that you may want to use. The first three deal with
|
183
|
+
errors and warnings and what to do with them.
|
184
|
+
|
185
|
+
* warning(a_string)
|
186
|
+
* error(a_string)
|
187
|
+
* abort_if_errors
|
188
|
+
|
189
|
+
cli_helper defines two arrays within configatron: errors and warnings. The
|
190
|
+
warning() and error() methods insert their strings into these arrays. The
|
191
|
+
abort_if_errors method first looks at the warnings array and presents all of
|
192
|
+
those strings to the user via STDOUT. It then asks the user if they want
|
193
|
+
to abort the program. The default answer is no.
|
194
|
+
|
195
|
+
After presenting the warnings to the user, the abort_if_error method presents
|
196
|
+
all of the errors to the user. Then it exits the program.
|
197
|
+
|
198
|
+
These next support methods are self explanatory:
|
199
|
+
|
200
|
+
* usage() #=> a_string
|
201
|
+
* show_usage() #=> usage string sent to STDOUT
|
202
|
+
* me() #=> The full path to the file that "require 'cli_helper"" was involked
|
203
|
+
* my_name() #=> the basename of me
|
204
|
+
|
205
|
+
But this one needs some explaining:
|
206
|
+
|
207
|
+
* get_pathnames_from(an_array, extnames=['.json', '.txt', '.docx'])
|
208
|
+
|
209
|
+
The method get_pathnames_from() returns an array of pathnames matching a specific
|
210
|
+
set of file types. The default types are txt, json and docx because that tends to
|
211
|
+
be the majority of the files in which I am interested. Might add wcml to the default list
|
212
|
+
later. Regardless you propabily ought to provide your own array of file extensions. And
|
213
|
+
don't forget the dot!
|
214
|
+
|
215
|
+
If an entry in the array is a directory then its children will be search including any sub-directories recursively.
|
216
|
+
|
217
|
+
Here is how I typically use it :)
|
218
|
+
|
219
|
+
```ruby
|
220
|
+
get_pathnames_from(configatron.arguments, '.php').each do |f|
|
221
|
+
f.delete_without_regret!
|
222
|
+
end
|
223
|
+
```
|
11
224
|
|
12
225
|
|
13
226
|
## Usage
|
14
227
|
|
15
|
-
|
16
|
-
for themselves.
|
228
|
+
Take a look at http://github.com/MadBomber/cli_helper/blob/master/example/cli_stub.rb
|
17
229
|
|
18
230
|
|
19
231
|
## License
|
20
232
|
|
21
233
|
You want it? Its yours.
|
22
|
-
# cli_helper
|
data/cli_helper.gemspec
CHANGED
@@ -4,18 +4,20 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "cli_helper"
|
7
|
-
spec.version = '0.0
|
7
|
+
spec.version = '0.1.0'
|
8
8
|
spec.authors = ["Dewayne VanHoozer"]
|
9
9
|
spec.email = ["dvanhoozer@gmail.com"]
|
10
10
|
|
11
|
-
spec.summary = %q{An
|
12
|
-
spec.description = %q{
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
spec.summary = %q{An encapsulation of an integration of slop, nenv, parseconfig and configatron.}
|
12
|
+
spec.description = %q{
|
13
|
+
An encapsulation of a convention I have been using
|
14
|
+
with the slop, nenv, parseconfig and configatron gems for quick and dirty
|
15
|
+
development of
|
16
|
+
command-line based utility programs. Slop parses ARGV; Nenv parses ENV;
|
17
|
+
ParseConfig parses INI; Configatron keeps it all together. YAML and ERB
|
18
|
+
preprocessing is also available. Ruby configuration files are also supported.
|
19
|
+
and you can specify multiple config files of mixed types at once.
|
20
|
+
}
|
19
21
|
spec.homepage = "http://github.com/MadBomber/cli_helper"
|
20
22
|
spec.license = "You want it? It's yours."
|
21
23
|
|
@@ -26,14 +28,15 @@ Gem::Specification.new do |spec|
|
|
26
28
|
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
27
29
|
end
|
28
30
|
|
29
|
-
spec.add_dependency '
|
31
|
+
spec.add_dependency 'configatron'
|
30
32
|
spec.add_dependency 'nenv'
|
31
|
-
spec.add_dependency '
|
32
|
-
spec.add_dependency '
|
33
|
-
|
33
|
+
spec.add_dependency 'parseconfig'
|
34
|
+
spec.add_dependency 'slop', "~> 4.0"
|
34
35
|
|
35
36
|
spec.add_development_dependency "bundler", "~> 1.9"
|
36
37
|
spec.add_development_dependency "rake", "~> 10.0"
|
37
|
-
spec.add_development_dependency '
|
38
|
+
spec.add_development_dependency 'kick_the_tires'
|
39
|
+
spec.add_development_dependency 'awesome_print'
|
40
|
+
spec.add_development_dependency 'debug_me'
|
38
41
|
|
39
42
|
end
|
data/example/cli_stub.rb
CHANGED
@@ -7,19 +7,55 @@
|
|
7
7
|
## By: Dewayne VanHoozer (dvanhoozer@gmail.com)
|
8
8
|
#
|
9
9
|
|
10
|
-
require '
|
11
|
-
|
12
|
-
$options[:version] = '0.0.1' # the version of this utility program
|
10
|
+
require 'awesome_print'
|
13
11
|
|
14
|
-
|
12
|
+
require 'cli_helper'
|
13
|
+
include CliHelper
|
14
|
+
|
15
|
+
configatron.version = '0.0.1' # the version of this utility program
|
16
|
+
configatron.support_config_files = true # default is false
|
17
|
+
configatron.disable_help = false # default is false set true to remove the option
|
18
|
+
configatron.disable_verbose = false # ditto
|
19
|
+
configatron.disable_debug = false # ditto
|
20
|
+
configatron.disable_version = false # ditto
|
21
|
+
configatron.suppress_errors = false # set to true to eat exceptions; unknown options added to arguments
|
22
|
+
|
23
|
+
# HELP is extra stuff shown with usage. It is optional. You
|
24
|
+
# can put anything you want into it. Since it is optional, it
|
25
|
+
# can be completely left out of your program. This HELP text
|
26
|
+
# will appear at the end of the usage message after the help
|
27
|
+
# text for each option (command-line parameter).
|
15
28
|
HELP = <<EOHELP
|
16
29
|
Important:
|
17
30
|
|
18
31
|
Put important stuff here.
|
19
32
|
|
33
|
+
Config files also support ERB preprocessing. use
|
34
|
+
cile names like: *.uml.erb *.ini.erb *.txt.erb
|
35
|
+
|
36
|
+
Do not use *.rb.erb that's just silly.
|
37
|
+
|
20
38
|
EOHELP
|
21
39
|
|
22
|
-
# The description (aka banner) text is optional. The block is required.
|
40
|
+
# The description (aka banner) text is optional. The block is not required.it
|
41
|
+
# only the default options and config files are desired. The block allows for
|
42
|
+
# the definition of program-specific options.
|
43
|
+
#
|
44
|
+
# Default options for help, debug, verbose, and version are automatically inserted
|
45
|
+
# by cli_helper. If configatron.support_config_files is TRUE then a '--config' parameter
|
46
|
+
# will also be presented. '--config' takes a comma-separated list of file paths. Each
|
47
|
+
# config file is processed within cli_helper and results combined within the configatron
|
48
|
+
# structure.
|
49
|
+
#
|
50
|
+
# -h, --help will automatically show a usage message on STDOUT and exit the program
|
51
|
+
# --version will print the program's version string to STDOUT and exit
|
52
|
+
# =v, --verbose will set the verbose boolean to true.
|
53
|
+
# -d, --debug will set the debug boolean to true.
|
54
|
+
# All boolean options have '?' and '!' methods generated, For example debug? and
|
55
|
+
# verbose? are automatically generated. Any program-specific booleans specified will
|
56
|
+
# also get methods defined for them. The debug! methods sets the debug boollean to true.
|
57
|
+
# Same for verbose! etc.
|
58
|
+
|
23
59
|
cli_helper("An example use of cli_helper") do |o|
|
24
60
|
|
25
61
|
# For a complete list of stuff see Slop on github.com
|
@@ -33,11 +69,13 @@ cli_helper("An example use of cli_helper") do |o|
|
|
33
69
|
|
34
70
|
o.array '-a', '--array', 'example array parameter', default: [:bob, :carol, :ted, :alice]
|
35
71
|
o.path '-p', '--path', 'example Pathname parameter', default: Pathname.new('default/path/to/file.txt')
|
36
|
-
o.paths '--paths', 'example Pathnames parameter', delimiter: ',', default: ['default/path/to/file.txt',
|
72
|
+
o.paths '--paths', 'example Pathnames parameter', delimiter: ',', default: ['default/path/to/file.txt',
|
73
|
+
'file2.txt'].map{|f| Pathname.new f}
|
37
74
|
|
38
75
|
# FIXME: Issue with Slop; default is not passed to the block. When no parameter is
|
39
76
|
# given, an exception is raised. Using the suppress_errors: true option silents
|
40
77
|
# the exception BUT still the default value is not passed to the block.
|
78
|
+
# This issue has been raised with the Slop author and a fix is in the works.
|
41
79
|
o.string '-n', '--name', 'print Hello <name>', default: 'World!', suppress_errors: true do |a_string|
|
42
80
|
a_string = 'world' if a_string.empty?
|
43
81
|
puts "Hello #{a_string}"
|
@@ -46,7 +84,7 @@ cli_helper("An example use of cli_helper") do |o|
|
|
46
84
|
end
|
47
85
|
|
48
86
|
# ARGV is not touched. However all command line parameters that are not consummed
|
49
|
-
# are available in
|
87
|
+
# are available in configatron.arguments
|
50
88
|
|
51
89
|
# Display the usage info
|
52
90
|
if ARGV.empty?
|
@@ -57,14 +95,29 @@ end
|
|
57
95
|
|
58
96
|
# Error check your stuff; use error('some message') and warning('some message')
|
59
97
|
|
60
|
-
unless
|
61
|
-
warning "These items were not processed #{
|
98
|
+
unless configatron.arguments.empty?
|
99
|
+
warning "These items were not processed #{configatron.arguments}"
|
62
100
|
end
|
63
101
|
|
64
|
-
if
|
102
|
+
if configatron.arguments.include?('error')
|
65
103
|
error "You wanted an error, so you got one."
|
66
104
|
end
|
67
105
|
|
106
|
+
if configatron.arguments.include?('warning')
|
107
|
+
warning "You wanted a warning, so you got one."
|
108
|
+
end
|
109
|
+
|
110
|
+
=begin
|
111
|
+
|
112
|
+
rescue
|
113
|
+
configatron.errors and configatron.warnings are of type Array.
|
114
|
+
All warnings will be presented to the user. The user will
|
115
|
+
be asked wither the program should be aborted.
|
116
|
+
=end
|
117
|
+
|
118
|
+
# present all warnings and all errors to the user
|
119
|
+
# if there are errors, the program will exit after
|
120
|
+
# displaying the error messages.
|
68
121
|
abort_if_errors
|
69
122
|
|
70
123
|
|
@@ -81,7 +134,7 @@ at_exit do
|
|
81
134
|
puts
|
82
135
|
end
|
83
136
|
|
84
|
-
ap
|
137
|
+
ap configatron.to_h if verbose? || debug?
|
85
138
|
|
86
139
|
stub = <<EOS
|
87
140
|
|