everyday-cli-utils 1.6.0 → 1.7.0

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: 0681993f800f4e74b8c294475c3ab23daeaed47b
4
- data.tar.gz: 88e392ad10471b71a496797a2dc07feb887e4a52
3
+ metadata.gz: cb60b2b94175b9d2d6b503d407375d04b1c15ffe
4
+ data.tar.gz: ab1222f03fb7b8bdc125f660ce84a6b96709aeda
5
5
  SHA512:
6
- metadata.gz: 333e611ce51e61d7299da6f573d1a8f9ff83a30c9da2a98b3bb0e9f91c73e389687522a0e1b74d602dcab6f4b43dd262c04663612426b72e13c49e013beb8d4e
7
- data.tar.gz: 64bc0c10b336847de4ea2b87377dd62c48d611a435e693aa563d5cd1c53380a7e792f5ca789b56a4359b4c1901259cbf200b435c0a594582e0c91947dcf9f477
6
+ metadata.gz: 608918b2d901514ab845218a5197c22bdbd7e41ae841173356dab982df8ea10f144eedc130fd8205d85101abc497ffcbc53c23d4508c881d5ddbf0460ea10849
7
+ data.tar.gz: afc31c86ee6c3c006aaf5bcc1ecc9e1d3c550c96dda42b170fdacc65d15c31d77648ec6274cd010123ea3a535b12251f1915146950e14d08dd34eaf7b32c3015
@@ -50,4 +50,20 @@ class Hash
50
50
  def expand
51
51
  EverydayCliUtils::MapUtil.expand(self)
52
52
  end
53
+
54
+ def clone
55
+ EverydayCliUtils::MapUtil.clone_hash(self)
56
+ end
57
+
58
+ def map(&block)
59
+ EverydayCliUtils::MapUtil.hashmap(self, &block);
60
+ end
61
+
62
+ def extend_hash(base_hash)
63
+ EverydayCliUtils::MapUtil.extend_hash(base_hash, self)
64
+ end
65
+
66
+ def -(hash2)
67
+ EverydayCliUtils::MapUtil.hash_diff(self, hash2)
68
+ end
53
69
  end
@@ -1,3 +1,4 @@
1
+ require_relative 'safe/maputil'
1
2
  require 'optparse'
2
3
  require 'yaml'
3
4
 
@@ -128,8 +129,7 @@ module EverydayCliUtils
128
129
  end
129
130
 
130
131
  def self.register(opts, options, type, opt_name, names, settings = {}, default_settings = {}, &block)
131
- settings = settings.clone
132
- default_settings.each { |v| settings[v[0]] = v[1] unless settings.has_key?(v[0]) }
132
+ settings = EverydayCliUtils::MapUtil.extend_hash(default_settings, settings)
133
133
  opt = OptionDef.new(type, names.clone, settings, &block)
134
134
  options[opt_name] = opt
135
135
  names = OptionTypes.mod_names(type, names, settings)
@@ -140,12 +140,51 @@ module EverydayCliUtils
140
140
  end
141
141
  end
142
142
 
143
+ class SpecialOptionDef
144
+ attr_reader :order, :settings, :names, :order
145
+ attr_accessor :state
146
+
147
+ def initialize(order, exit_on_action, names, print_on_exit_str, settings, action_block, pre_parse_block = nil)
148
+ @order = order
149
+ @exit_on_action = exit_on_action
150
+ @names = names
151
+ @print_on_exit_str = print_on_exit_str
152
+ @settings = settings
153
+ @action_block = action_block
154
+ @pre_parse_block = pre_parse_block
155
+ @state = false
156
+ end
157
+
158
+ def run(options_list)
159
+ if @state
160
+ @action_block.call(self, options_list)
161
+ if @exit_on_action
162
+ puts @print_on_exit_str unless @print_on_exit_str.nil?
163
+ exit 0
164
+ end
165
+ end
166
+ end
167
+
168
+ def run_pre_parse(options_list)
169
+ @pre_parse_block.call(self, options_list) unless @pre_parse_block.nil?
170
+ end
171
+
172
+ def self.register(order, opts, options, opt_name, names, exit_on_action, print_on_exit_str, settings, default_settings, action_block, pre_parse_block = nil)
173
+ settings = EverydayCliUtils::MapUtil.extend_hash(default_settings, settings)
174
+ opt = SpecialOptionDef.new(order, exit_on_action, names, print_on_exit_str, settings, action_block, pre_parse_block)
175
+ options.special_options[opt_name] = opt
176
+ names << settings[:desc] if settings.has_key?(:desc)
177
+ opts.on(*names) { opt.state = true }
178
+ end
179
+ end
180
+
143
181
  class OptionList
144
- attr_reader :opts
182
+ attr_reader :opts, :special_options
145
183
  attr_accessor :default_settings, :help_str
146
184
 
147
185
  def initialize
148
186
  @options = {}
187
+ @special_options = {}
149
188
  @default_settings = {}
150
189
  @opts = OptionParser.new
151
190
  @help_str = nil
@@ -159,12 +198,32 @@ module EverydayCliUtils
159
198
  @options[opt_name].set(value) if @options.has_key?(opt_name)
160
199
  end
161
200
 
201
+ def set_all(opts)
202
+ opts.each { |opt| set(opt[0], opt[1]) }
203
+ end
204
+
162
205
  def update(opt_name, value, layer)
163
206
  @options[opt_name].update(value, layer) if @options.has_key?(opt_name)
164
207
  end
165
208
 
209
+ def update_all(layer, opts)
210
+ opts.each { |opt| update(opt[0], opt[1], layer) }
211
+ end
212
+
166
213
  def register(type, opt_name, names, settings = {}, &block)
167
- OptionDef.register(@opts, @options, type, opt_name, names, settings, @default_settings, &block)
214
+ OptionDef.register(@opts, self, type, opt_name, names, settings, @default_settings, &block)
215
+ end
216
+
217
+ def register_special(order, opt_name, names, exit_on_action, print_on_exit_str, settings, action_block, pre_parse_block = nil)
218
+ SpecialOptionDef.register(order, @opts, self, opt_name, names, exit_on_action, print_on_exit_str, settings, @default_settings, action_block, pre_parse_block)
219
+ end
220
+
221
+ def run_special
222
+ @special_options.to_a.sort_by { |v| v[1].order }.each { |v| v[1].run(self) }
223
+ end
224
+
225
+ def run_special_pre_parse
226
+ @special_options.to_a.sort_by { |v| v[1].order }.each { |v| v[1].run_pre_parse(self) }
168
227
  end
169
228
 
170
229
  def composite(*layers)
@@ -193,28 +252,22 @@ module EverydayCliUtils
193
252
  script_defaults = composite
194
253
  global_defaults = composite(:global)
195
254
  local_defaults = composite(:global, :local)
196
- global_diff = hash_diff(global_defaults, script_defaults)
197
- local_diff = hash_diff(local_defaults, global_defaults)
255
+ global_diff = EverydayCliUtils::MapUtil.hash_diff(global_defaults, script_defaults)
256
+ local_diff = EverydayCliUtils::MapUtil.hash_diff(local_defaults, global_defaults)
198
257
  str = "Script Defaults:\n#{options_to_str(script_defaults)}\n"
199
258
  str << "Script + Global Defaults:\n#{options_to_str(global_diff)}\n" unless global_diff.empty?
200
259
  str << "Script + Global + Local Defaults:\n#{options_to_str(local_diff)}\n" unless local_diff.empty?
201
260
  str
202
261
  end
203
262
 
204
- def hash_diff(hash1, hash2)
205
- new_hash = {}
206
- hash1.keys.each { |k| new_hash[k] = hash1[k] unless hash2.has_key?(k) && hash1[k] == hash2[k] }
207
- new_hash
208
- end
209
-
210
- def options_to_str(options)
263
+ def options_to_str(options, indent = 4)
211
264
  str = ''
212
265
  max_name_len = @options.values.map { |v| v.names.join(', ').length }.max
213
266
  options.each { |v|
214
267
  opt = @options[v[0]]
215
268
  val = v[1]
216
269
  names_str = opt.names.join(', ')
217
- str << "#{' ' * 4}#{names_str}#{' ' * ((max_name_len + 4) - names_str.length)}#{val_to_str(val)}\n"
270
+ str << "#{' ' * indent}#{names_str}#{' ' * ((max_name_len + 4) - names_str.length)}#{val_to_str(val)}\n"
218
271
  }
219
272
  str
220
273
  end
@@ -248,37 +301,45 @@ module EverydayCliUtils
248
301
  end
249
302
 
250
303
  def defaults_option(file_path, names, settings = {})
251
- @options ||= OptionList.new
252
- @set_defaults = false
253
- @defaults_file = File.expand_path(file_path)
254
- @exit_on_save = !settings.has_key?(:exit_on_save) || settings[:exit_on_save]
255
- names << settings[:desc] if settings.has_key?(:desc)
256
- @options.opts.on(*names) { @set_defaults = true }
304
+ @options ||= OptionList.new
305
+ settings[:file_path] = file_path
306
+ @options.register_special(4, :defaults, names, settings[:exit_on_save], 'Defaults set', settings,
307
+ ->(opt, options) {
308
+ IO.write(opt.settings[:file_path], options.composite(:local, :arg).to_yaml)
309
+ }, ->(opt, options) {
310
+ unless opt.settings[:file_path].nil? || !File.exist?(opt.settings[:file_path])
311
+ options.update_all :local, YAML::load_file(opt.settings[:file_path])
312
+ end
313
+ })
257
314
  end
258
315
 
259
316
  def global_defaults_option(file_path, names, settings = {})
260
- @options ||= OptionList.new
261
- @set_global_defaults = false
262
- @global_defaults_file = File.expand_path(file_path)
263
- @exit_on_global_save = !settings.has_key?(:exit_on_save) || settings[:exit_on_save]
264
- names << settings[:desc] if settings.has_key?(:desc)
265
- @options.opts.on(*names) { @set_global_defaults = true }
317
+ @options ||= OptionList.new
318
+ settings[:file_path] = file_path
319
+ @options.register_special(3, :global_defaults, names, settings[:exit_on_save], 'Global defaults set', settings,
320
+ ->(opt, options) {
321
+ IO.write(opt.settings[:file_path], options.composite(:global, :arg).to_yaml)
322
+ }, ->(opt, options) {
323
+ unless opt.settings[:file_path].nil? || !File.exist?(opt.settings[:file_path])
324
+ options.update_all :global, YAML::load_file(opt.settings[:file_path])
325
+ end
326
+ })
266
327
  end
267
328
 
268
329
  def show_defaults_option(names, settings = {})
269
- @options ||= OptionList.new
270
- @show_defaults = false
271
- @exit_on_show_defaults = !settings.has_key?(:exit_on_show) || settings[:exit_on_show]
272
- names << settings[:desc] if settings.has_key?(:desc)
273
- @options.opts.on(*names) { @show_defaults = true }
330
+ @options ||= OptionList.new
331
+ @options.register_special(2, :show_defaults, names, settings[:exit_on_show], nil, settings,
332
+ ->(_, options) {
333
+ puts options.show_defaults
334
+ })
274
335
  end
275
336
 
276
337
  def help_option(names, settings = {})
277
- @options ||= OptionList.new
278
- @display_help = false
279
- @exit_on_print = !settings.has_key?(:exit_on_print) || settings[:exit_on_print]
280
- names << settings[:desc] if settings.has_key?(:desc)
281
- @options.opts.on(*names) { @display_help = true }
338
+ @options ||= OptionList.new
339
+ @options.register_special(1, :help, names, settings[:exit_on_print], nil, settings,
340
+ ->(_, options) {
341
+ puts options.help
342
+ })
282
343
  end
283
344
 
284
345
  def default_settings(settings = {})
@@ -288,12 +349,12 @@ module EverydayCliUtils
288
349
 
289
350
  def default_options(opts = {})
290
351
  @options ||= OptionList.new
291
- opts.each { |opt| @options.set(opt[0], opt[1]) }
352
+ @options.set_all(opts)
292
353
  end
293
354
 
294
355
  def apply_options(layer, opts = {})
295
356
  @options ||= OptionList.new
296
- opts.each { |opt| @options.update(opt[0], opt[1], layer) }
357
+ @options.update_all(layer, opts)
297
358
  end
298
359
 
299
360
  def banner(banner)
@@ -329,30 +390,9 @@ module EverydayCliUtils
329
390
 
330
391
  def parse!(argv = ARGV)
331
392
  @options ||= OptionList.new
332
- apply_options :global, YAML::load_file(@global_defaults_file) unless @global_defaults_file.nil? || !File.exist?(@global_defaults_file)
333
- apply_options :local, YAML::load_file(@defaults_file) unless @defaults_file.nil? || !File.exist?(@defaults_file)
393
+ @options.run_special_pre_parse
334
394
  @options.parse!(argv)
335
- if @display_help
336
- puts help
337
- exit 0 if @exit_on_print
338
- end
339
- if @show_defaults
340
- puts @options.show_defaults
341
- exit 0 if @exit_on_show_defaults
342
- end
343
- if @set_global_defaults
344
- IO.write(@global_defaults_file, @options.composite(:global, :arg).to_yaml)
345
- if @exit_on_global_save
346
- puts 'Global defaults set'
347
- exit 0
348
- end
349
- elsif @set_defaults
350
- IO.write(@defaults_file, @options.composite(:local, :arg).to_yaml)
351
- if @exit_on_save
352
- puts 'Defaults set'
353
- exit 0
354
- end
355
- end
395
+ @options.run_special
356
396
  end
357
397
  end
358
398
  end
@@ -58,5 +58,27 @@ module EverydayCliUtils
58
58
  }
59
59
  rval
60
60
  end
61
+
62
+ def self.hashmap(hash, &block)
63
+ new_hash = {}
64
+ block_given? ? hash.each { |v| new_hash[v[0]] = block.call(v) } : hash.each { |v| new_hash[v[0]] = v[1] } unless hash.nil?
65
+ new_hash
66
+ end
67
+
68
+ def self.clone_hash(hash)
69
+ hashmap(hash)
70
+ end
71
+
72
+ def self.extend_hash(base_hash, extending_hash)
73
+ result_hash = clone_hash(extending_hash)
74
+ base_hash.each { |v| result_hash[v[0]] = v[1] unless result_hash.has_key?(v[0]) }
75
+ result_hash
76
+ end
77
+
78
+ def self.hash_diff(hash1, hash2)
79
+ new_hash = {}
80
+ hash1.keys.each { |k| new_hash[k] = hash1[k] unless hash2.has_key?(k) && hash1[k] == hash2[k] }
81
+ new_hash
82
+ end
61
83
  end
62
84
  end
@@ -1,3 +1,3 @@
1
1
  module EverydayCliUtils
2
- VERSION = '1.6.0'
2
+ VERSION = '1.7.0'
3
3
  end
@@ -68,4 +68,25 @@ describe 'maputil' do
68
68
  expected = { a: '1-4', b: '1-4', c: '1-4', d: '1-4', :e => '5' }
69
69
  expanded.should eq expected
70
70
  end
71
+
72
+ it 'provides a means of cloning a hash' do
73
+ hash = { a: 1, b: 2, c: 3, d: 4, e: 5 }
74
+ cloned = hash.clone
75
+ hash.should_not equal cloned
76
+ end
77
+
78
+ it 'provides a means of using map with a hash' do
79
+ hash = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }
80
+ mapped = hash.map { |v| v[1] + ((v[0] == :a || v[0] == :c || v[0] == :e) ? 1 : -1) }
81
+ expected = { a: 2, b: 1, c: 4, d: 3, e: 6, f: 5}
82
+ mapped.should eq expected
83
+ end
84
+
85
+ it 'provides a means of extending one hash with another' do
86
+ hash1 = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }
87
+ hash2 = { a: 11, d: 14, f: 16 }
88
+ extended = hash2.extend_hash(hash1)
89
+ expected = { a: 11, b: 2, c: 3, d: 14, e: 5, f: 16 }
90
+ extended.should eq expected
91
+ end
71
92
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: everyday-cli-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Henderson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-05 00:00:00.000000000 Z
11
+ date: 2014-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler