everyday-cli-utils 1.6.0 → 1.7.0

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: 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