cli_helper 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f89331e703cf232785ca8d53326636cfa11c8cd8
4
- data.tar.gz: 5481796f66cdf9112a887eccffb2f6db4da5db13
3
+ metadata.gz: 908f129ebd9c858f0b8a5f63216db870545ba9f6
4
+ data.tar.gz: a839ae1f117642b1edcf34dbfba1d5c2906e3e0e
5
5
  SHA512:
6
- metadata.gz: f68d31b2f94d5086e2ac90a0e24e65aa4218195a136eb2984fdb7aa5a1e30ac4dcff9393e71519a51d9e229e70edccac4ecc110d7b03f76f63d0f5b487c32b9f
7
- data.tar.gz: 519b04e19531eaa4269264ace89ab7614b91e9970c8d743db34dac760d78b5fb86bfebc0291ba8f83dc9a54f96831ac0f171c37ca60f72ee130e1199ff551808
6
+ metadata.gz: ca4ac6875722b4caee01dec81a725e872ec4caae88f9d9ac0adb9b291a385e50c9f831a137838749d6fbea6422b801369eb5745b7044684b9e82b020cd53cecf
7
+ data.tar.gz: 5aee6b729080af581763f64add1685393e8d33814cf4be74eb6628c8f8f0e6a92385a6a26f3c3ef1fb4c6f24a4de8283d7a11e78c8fbcf75d046161a3d1e20d5
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cli_helper.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # cli_helper.rb
2
+
3
+ I had this code just being lazy on my computer. It might be of use
4
+ to someone else; but, its just really intended to support my own
5
+ quick and dirty command-line based utilities. Mostly they are one-offs
6
+ but sometimes they hang around.
7
+
8
+ I typically create thes cli utilities using my own code generater which
9
+ resulted in lots of duplicate source blocks roll around on the deck. This
10
+ little library will DRYup my code a little.
11
+
12
+
13
+ ## Usage
14
+
15
+ TODO: Write usage instructions here in case someone can't figure it out
16
+ for themselves.
17
+
18
+
19
+ ## License
20
+
21
+ You want it? Its yours.
22
+ # cli_helper
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "cli_helper"
7
+ spec.version = '0.0.2'
8
+ spec.authors = ["Dewayne VanHoozer"]
9
+ spec.email = ["dvanhoozer@gmail.com"]
10
+
11
+ spec.summary = %q{An encapsulates of common junk used with Q&D CLI utilities.}
12
+ spec.description = %q{An encapsulation of a convention I have been using
13
+ with the slop, nenv, and other gems for quick and dirty development of
14
+ command-line based utility programs. Its not pretty. It may even break
15
+ your code. I wouldn't use it if I were you. You could, if you wanted,
16
+ namespace this stuff within CliHelper and establish a new convention.
17
+ You might even wrap not only slop but some of those other ARGV parsers.
18
+ I only did this much after being shamed into it by rubycritic.}
19
+ spec.homepage = "http://github.com/MadBomber/cli_helper"
20
+ spec.license = "You want it? It's yours."
21
+
22
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
23
+ spec.require_paths = ["lib"]
24
+
25
+ if spec.respond_to?(:metadata)
26
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
27
+ end
28
+
29
+ spec.add_dependency 'slop'
30
+ spec.add_dependency 'nenv'
31
+ spec.add_dependency 'awesome_print'
32
+
33
+ spec.add_development_dependency "bundler", "~> 1.8"
34
+ spec.add_development_dependency "rake", "~> 10.0"
35
+ spec.add_development_dependency 'test_inline'
36
+
37
+ end
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ ##########################################################
4
+ ###
5
+ ## File: cli_stub.rb
6
+ ## Desc: Example on how to use cli_helper for q&d CLI utilities
7
+ ## By: Dewayne VanHoozer (dvanhoozer@gmail.com)
8
+ #
9
+
10
+ require 'cli_helper'
11
+
12
+ $options[:version] = '0.0.1' # the version of this utility program
13
+
14
+ # HELP is extra stuff shown with usage. It is optional.
15
+ HELP = <<EOHELP
16
+ Important:
17
+
18
+ Put important stuff here.
19
+
20
+ EOHELP
21
+
22
+ # The description (aka banner) text is optional. The block is required.
23
+ cli_helper("An example use of cli_helper") do |o|
24
+
25
+ # For a complete list of stuff see Slop on github.com
26
+ # https://github.com/leejarvis/slop
27
+
28
+ o.string '-s', '--string', 'example string parameter', default: 'IamDefault'
29
+ o.int '-i', '--int', 'example integer parameter', default: 42
30
+
31
+ # FIXME: an issue with Slop
32
+ #o.float '-f', '--float', 'example float parameter', default: (22.0 / 7.0)
33
+
34
+ o.array '-a', '--array', 'example array parameter', default: [:bob, :carol, :ted, :alice]
35
+ 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', 'file2.txt'].map{|f| Pathname.new f}
37
+
38
+ # FIXME: Issue with Slop; default is not passed to the block. When no parameter is
39
+ # given, an exception is raised. Using the suppress_errors: true option silents
40
+ # the exception BUT still the default value is not passed to the block.
41
+ o.string '-n', '--name', 'print Hello <name>', default: 'World!', suppress_errors: true do |a_string|
42
+ a_string = 'world' if a_string.empty?
43
+ puts "Hello #{a_string}"
44
+ end
45
+
46
+ end
47
+
48
+ # ARGV is not touched. However all command line parameters that are not consummed
49
+ # are available in $options[:arguments]
50
+
51
+ # Display the usage info
52
+ if ARGV.empty?
53
+ show_usage
54
+ exit
55
+ end
56
+
57
+
58
+ # Error check your stuff; use error('some message') and warning('some message')
59
+
60
+ unless $options[:arguments].empty?
61
+ warning "These items were not processed #{$options[:arguments]}"
62
+ end
63
+
64
+ if $options[:arguments].include?('error')
65
+ error "You wanted an error, so you got one."
66
+ end
67
+
68
+ abort_if_errors
69
+
70
+
71
+ ######################################################
72
+ # Local methods
73
+
74
+
75
+ ######################################################
76
+ # Main
77
+
78
+ at_exit do
79
+ puts
80
+ puts "Done."
81
+ puts
82
+ end
83
+
84
+ ap $options if verbose? || debug?
85
+
86
+ stub = <<EOS
87
+
88
+
89
+ d888888o. 8888888 8888888888 8 8888 88 8 888888888o
90
+ .`8888:' `88. 8 8888 8 8888 88 8 8888 `88.
91
+ 8.`8888. Y8 8 8888 8 8888 88 8 8888 `88
92
+ `8.`8888. 8 8888 8 8888 88 8 8888 ,88
93
+ `8.`8888. 8 8888 8 8888 88 8 8888. ,88'
94
+ `8.`8888. 8 8888 8 8888 88 8 8888888888
95
+ `8.`8888. 8 8888 8 8888 88 8 8888 `88.
96
+ 8b `8.`8888. 8 8888 ` 8888 ,8P 8 8888 88
97
+ `8b. ;8.`8888 8 8888 8888 ,d8P 8 8888 ,88'
98
+ `Y8888P ,88P' 8 8888 `Y88888P' 8 888888888P
99
+
100
+
101
+ EOS
102
+
103
+ puts stub
104
+
data/lib/cli_helper.rb ADDED
@@ -0,0 +1,325 @@
1
+ # encoding: utf-8
2
+ ##########################################################
3
+ ###
4
+ ## File: cli_helper.rb
5
+ ## Desc: Some DRYed up stuff for quick and dirty CLI utilities
6
+ ## By: Dewayne VanHoozer (dvanhoozer@gmail.com)
7
+ #
8
+
9
+ #require 'test_inline'
10
+
11
+ # NOTE: this conditional required by test_inline
12
+ if caller.empty?
13
+ required_by_filename = __FILE__
14
+ else
15
+ required_by_filename = caller.last.split(':').first
16
+ end
17
+
18
+ require 'debug_me'
19
+ include DebugMe
20
+
21
+ require 'awesome_print'
22
+
23
+ require 'pathname'
24
+ require 'nenv'
25
+ require 'slop'
26
+
27
+ # Example Custom Type for Slop
28
+ module Slop
29
+ class PathOption < Option
30
+ def call(value)
31
+ Pathname.new(value)
32
+ end
33
+ end
34
+ class PathsOption < ArrayOption
35
+ def finish(opts)
36
+ self.value = value.map { |f| Pathname.new(f) }
37
+ end
38
+ end
39
+ end # module Slop
40
+
41
+ $cli = 'a place holder'
42
+ $errors = []
43
+ $warnings = []
44
+
45
+ $options = {
46
+ version: '0.0.1',# the version of this program
47
+ arguments: [], # whats left after options and parameters are extracted
48
+ verbose: false,
49
+ debug: false,
50
+ help: false,
51
+ user_name: Nenv.user || Nenv.user_name || Nenv.logname || 'Dewayne VanHoozer',
52
+ me: Pathname.new(required_by_filename).realpath,
53
+ home_path: Pathname.new(Nenv.home)
54
+ }
55
+
56
+ $options[:my_dir] = $options[:me].parent
57
+ $options[:my_name] = $options[:me].basename.to_s
58
+
59
+ # Return full pathname of program
60
+ def me
61
+ $options[:me]
62
+ end
63
+
64
+ # Returns the basename of the program as a string
65
+ def my_name
66
+ $options[:my_name]
67
+ end
68
+
69
+ # Returns the version of the program as a string
70
+ def version
71
+ $options[:version]
72
+ end
73
+
74
+ # Invoke Slop with common CLI parameters and custom
75
+ # parameters provided via a block. Create '?'
76
+ # for all boolean parameters that have a '--name' flag form.
77
+ # Returns a Slop::Options object
78
+ def cli_helper(my_banner='')
79
+ param = Slop::Options.new
80
+
81
+ if my_banner.empty?
82
+ param.banner = "Usage: #{my_name} [options] ..."
83
+ else
84
+ param.banner = my_banner
85
+ param.separator "\nUsage: #{my_name} [options] ..."
86
+ end
87
+
88
+ param.separator "\nWhere:"
89
+ param.separator " Common Options Are:"
90
+
91
+ param.bool '-h', '--help', 'show this message'
92
+ param.bool '-v', '--verbose', 'enable verbose mode'
93
+ param.bool '-d', '--debug', 'enable debug mode'
94
+
95
+ param.on '--version', "print the version: #{$options[:version]}" do
96
+ puts $options[:version]
97
+ exit
98
+ end
99
+
100
+ param.separator " Program Options Are:"
101
+
102
+ yield(param) if block_given?
103
+
104
+ parser = Slop::Parser.new(param)
105
+ $cli = parser.parse(ARGV)
106
+
107
+ $options.merge!($cli.to_hash)
108
+ $options[:arguments] = $cli.arguments
109
+
110
+
111
+ bools = param.options.select do |o|
112
+ o.is_a? Slop::BoolOption
113
+ end.select{|o| o.flags.select{|f|f.start_with?('--')}}.
114
+ map{|o| o.flags.last.gsub('--','')} # SMELL: depends on convention
115
+
116
+ bools.each do |m|
117
+ s = m.to_sym
118
+ define_method(m+'?') do
119
+ $options[s]
120
+ end unless self.respond_to?(m+'?')
121
+ define_method(m+'!') do
122
+ $options[s] = true
123
+ end unless self.respond_to?(m+'!')
124
+ end
125
+
126
+ if help?
127
+ show_usage
128
+ exit
129
+ end
130
+
131
+ return param
132
+ end # cli_helper
133
+
134
+ # Returns the usage/help information as a string
135
+ def usage
136
+ a_string = $cli.to_s + "\n"
137
+ a_string += HELP + "\n" if defined?(HELP)
138
+ return a_string
139
+ end
140
+
141
+ # Prints to STDOUT the usage/help string
142
+ def show_usage
143
+ puts usage()
144
+ end
145
+
146
+
147
+ # Returns an array of valid files of one type
148
+ def get_pathnames_from(an_array, extnames=['.json', '.txt', '.docx'])
149
+ an_array = [an_array] unless an_array.is_a? Array
150
+ extnames = [extnames] unless extnames.is_a? Array
151
+ extnames = extnames.map{|e| e.downcase}
152
+ file_array = []
153
+ an_array.each do |a|
154
+ pfn = Pathname.new(a)
155
+ if pfn.directory?
156
+ file_array << get_pathnames_from(pfn.children, extnames)
157
+ else
158
+ file_array << pfn if pfn.exist? && extnames.include?(pfn.extname.downcase)
159
+ end
160
+ end
161
+ return file_array.flatten
162
+ end # def get_pathnames_from(an_array, extname='.json')
163
+
164
+
165
+ # Display global warnings and errors arrays and exit if necessary
166
+ def abort_if_errors
167
+ unless $warnings.empty?
168
+ STDERR.puts
169
+ STDERR.puts "The following warnings were generated:"
170
+ STDERR.puts
171
+ $warnings.each do |w|
172
+ STDERR.puts "\tWarning: #{w}"
173
+ end
174
+ STDERR.print "\nAbort program? (y/N) "
175
+ answer = (STDIN.gets).chomp.strip.downcase
176
+ $errors << "Aborted by user" if answer.size>0 && 'y' == answer[0]
177
+ $warnings = []
178
+ end
179
+ unless $errors.empty?
180
+ STDERR.puts
181
+ STDERR.puts "Correct the following errors and try again:"
182
+ STDERR.puts
183
+ $errors.each do |e|
184
+ STDERR.puts "\t#{e}"
185
+ end
186
+ STDERR.puts
187
+ exit(-1)
188
+ end
189
+ end # def abort_if_errors
190
+
191
+ # Adds a string to the global $errors array
192
+ def error(a_string)
193
+ $errors << a_string
194
+ end
195
+
196
+ # Adds a string to the global $warnings array
197
+ def warning(a_string)
198
+ $warnings << a_string
199
+ end
200
+
201
+
202
+ __END__
203
+ ################################################
204
+ ## Here is how it works
205
+
206
+ Test '000 supports basic common parameters' do
207
+ params = cli_helper
208
+ assert params.is_a? Slop::Options
209
+ assert usage.include?('--help')
210
+ assert usage.include?('--debug')
211
+ assert usage.include?('--verbose')
212
+ assert usage.include?('--version')
213
+ refute usage.include?('--xyzzy')
214
+ end
215
+
216
+ =begin
217
+ # NOTE: The Test construct creates a dynamic class which
218
+ # does not incorporate 'define_method' This Test results
219
+ # in errors that are a consequence of the testing framework
220
+ # not the object under test.
221
+ Test '002 creates accessor methods to boolean options' do
222
+ cli_helper
223
+ all_methods = methods
224
+ %w[ help? debug? verbose? version?
225
+ help! debug! verbose! version!].each do |m|
226
+ assert all_methods.include?(m)
227
+ end
228
+ refute all_methods.include?('xyzzy?')
229
+ refute all_methods.include?('xyzzy!')
230
+ end
231
+ =end
232
+
233
+ Test '005 block inclusion' do
234
+ cli_helper do |param|
235
+ param.string '-x', '--xyxxy', 'example MAGIC parameter', default: 'IamDefault'
236
+ end
237
+ assert usage.include?('MAGIC')
238
+ end
239
+
240
+ Test '010 supports banner' do
241
+ refute usage().include?('BANNER')
242
+ cli_helper('This is my BANNER')
243
+ assert usage().include?('BANNER')
244
+ end
245
+
246
+ Test '015 supports additional help in usage' do
247
+ refute usage.include?('HELP')
248
+ HELP = "Do you need some HELP?"
249
+ assert usage.include?('HELP')
250
+ end
251
+
252
+ Test '020 put it all together' do
253
+ cli_helper('This is my BANNER') do |o|
254
+ o.string '-x', '--xyxxy', 'example MAGIC parameter', default: 'IamDefault'
255
+ end
256
+ HELP = "Do you need some HELP?"
257
+ assert usage.include?('BANNER')
258
+ assert usage.include?('MAGIC')
259
+ assert usage.include?('HELP')
260
+ end
261
+
262
+ Test '025 Add to $errors' do
263
+ assert $errors.empty?
264
+ a_message = 'There is a serious problem here'
265
+ error a_message
266
+ refute $errors.empty?
267
+ assert_equal 1, $errors.size
268
+ assert_equal a_message, $errors.first
269
+ end
270
+
271
+ Test '030 Add to $warnings' do
272
+ assert $warnings.empty?
273
+ a_message = 'There is a minor problem here'
274
+ warning a_message
275
+ refute $warnings.empty?
276
+ assert_equal 1, $warnings.size
277
+ assert_equal a_message, $warnings.first
278
+ end
279
+
280
+ Test '035 Add to $errors' do
281
+ refute $errors.empty?
282
+ a_message = 'There is another serious problem here'
283
+ error a_message
284
+ assert_equal 2, $errors.size
285
+ assert_equal a_message, $errors.last
286
+ end
287
+
288
+ Test '040 Add to $warnings' do
289
+ refute $warnings.empty?
290
+ a_message = 'There is a another minor problem here'
291
+ warning a_message
292
+ assert_equal 2, $warnings.size
293
+ assert_equal a_message, $warnings.last
294
+ end
295
+
296
+
297
+
298
+
299
+
300
+ Test '999 prints usage()' do
301
+ puts
302
+ puts "="*45
303
+ show_usage
304
+ puts "="*45
305
+ puts
306
+ a_string = <<EOS
307
+ This is my BANNER
308
+
309
+ Usage: cli_helper.rb [options] ...
310
+
311
+ Where:
312
+ Common Options Are:
313
+ -h, --help show this message
314
+ -v, --verbose enable verbose mode
315
+ -d, --debug enable debug mode
316
+ --version print the version: 0.0.1
317
+ Program Options Are:
318
+ -x, --xyxxy example MAGIC parameter
319
+
320
+ Do you need some HELP?
321
+ EOS
322
+
323
+ assert_equal a_string, usage
324
+ end
325
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cli_helper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dewayne VanHoozer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-17 00:00:00.000000000 Z
11
+ date: 2015-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: slop
@@ -94,22 +94,32 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
- description: An encapsulation of a convention I have been using with the slop, nenv,
98
- and other gems for quick and dirty development of command-line based utility programs. Its
99
- not pretty. It may even break your code. I wouldn't use it if I were you. You
100
- could, if you wanted, namespace this stuff within CliHelper and establish a new
101
- convention. You might even wrap not only slop but some of those other ARGV parsers. I
102
- only did this much after being shamed into it by rubycritic.
97
+ description: |-
98
+ An encapsulation of a convention I have been using
99
+ with the slop, nenv, and other gems for quick and dirty development of
100
+ command-line based utility programs. Its not pretty. It may even break
101
+ your code. I wouldn't use it if I were you. You could, if you wanted,
102
+ namespace this stuff within CliHelper and establish a new convention.
103
+ You might even wrap not only slop but some of those other ARGV parsers.
104
+ I only did this much after being shamed into it by rubycritic.
103
105
  email:
104
106
  - dvanhoozer@gmail.com
105
107
  executables: []
106
108
  extensions: []
107
109
  extra_rdoc_files: []
108
- files: []
110
+ files:
111
+ - ".gitignore"
112
+ - Gemfile
113
+ - README.md
114
+ - Rakefile
115
+ - cli_helper.gemspec
116
+ - example/cli_stub.rb
117
+ - lib/cli_helper.rb
109
118
  homepage: http://github.com/MadBomber/cli_helper
110
119
  licenses:
111
- - You want it? Its yours.
112
- metadata: {}
120
+ - You want it? It's yours.
121
+ metadata:
122
+ allowed_push_host: https://rubygems.org
113
123
  post_install_message:
114
124
  rdoc_options: []
115
125
  require_paths:
@@ -126,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
126
136
  version: '0'
127
137
  requirements: []
128
138
  rubyforge_project:
129
- rubygems_version: 2.4.4
139
+ rubygems_version: 2.4.6
130
140
  signing_key:
131
141
  specification_version: 4
132
142
  summary: An encapsulates of common junk used with Q&D CLI utilities.