cli_helper 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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.