markdown_exec 1.3.2 → 1.3.3.1
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 +4 -4
- data/.rubocop.yml +13 -11
- data/CHANGELOG.md +40 -3
- data/Gemfile +6 -3
- data/Gemfile.lock +112 -34
- data/README.md +5 -84
- data/Rakefile +105 -28
- data/bin/tab_completion.sh +2 -2
- data/lib/cached_nested_file_reader.rb +115 -0
- data/lib/colorize.rb +4 -0
- data/lib/env.rb +1 -0
- data/lib/env_opts.rb +54 -56
- data/lib/environment_opt_parse.rb +24 -19
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +589 -260
- data/lib/menu.yml +70 -4
- data/lib/object_present.rb +44 -0
- data/lib/rspec_helpers.rb +10 -0
- data/lib/tap.rb +51 -7
- metadata +4 -4
- data/lib/globfiles.rb +0 -40
- data/lib/yaml_env_opts.rb +0 -60
data/Rakefile
CHANGED
@@ -30,7 +30,6 @@ require_relative 'lib/tap'
|
|
30
30
|
include CLI
|
31
31
|
|
32
32
|
include Tap
|
33
|
-
tap_config envvar: MarkdownExec::TAP_DEBUG
|
34
33
|
|
35
34
|
RuboCop::RakeTask.new do |task|
|
36
35
|
task.requires << 'rubocop-minitest'
|
@@ -42,12 +41,6 @@ task :rubocopminitest do
|
|
42
41
|
`rubocop --require rubocop-minitest`
|
43
42
|
end
|
44
43
|
|
45
|
-
# desc 'rspec'
|
46
|
-
# task :rspec do
|
47
|
-
# puts "in rspec"
|
48
|
-
# `pwd && rspec`
|
49
|
-
# end
|
50
|
-
|
51
44
|
task default: %i[test reek rubocop rubocopminitest]
|
52
45
|
# task default: %i[rspec test reek rubocop rubocopminitest]
|
53
46
|
|
@@ -80,6 +73,12 @@ task :clean do
|
|
80
73
|
system 'rm *.gem'
|
81
74
|
end
|
82
75
|
|
76
|
+
desc 'minitest'
|
77
|
+
task :minitest do
|
78
|
+
puts `bundle exec ruby ./lib/object_present.rb`
|
79
|
+
puts `bundle exec ruby ./lib/cached_nested_file_reader.rb`
|
80
|
+
end
|
81
|
+
|
83
82
|
desc 'reek'
|
84
83
|
task :reek do
|
85
84
|
`reek --config .reek .`
|
@@ -244,15 +243,58 @@ task :update_menu_yml do
|
|
244
243
|
|
245
244
|
## secondary options
|
246
245
|
#
|
246
|
+
{
|
247
|
+
arg_name: 'BOOL',
|
248
|
+
default: false,
|
249
|
+
description: 'Display only blocks of type "bash"',
|
250
|
+
env_var: 'MDE_BASH_ONLY',
|
251
|
+
opt_name: 'bash_only',
|
252
|
+
procname: 'val_as_bool'
|
253
|
+
},
|
247
254
|
{
|
248
255
|
arg_name: "INT.#{DISPLAY_LEVEL_BASE}-#{DISPLAY_LEVEL_MAX}",
|
249
256
|
default: DISPLAY_LEVEL_DEFAULT,
|
250
|
-
description:
|
257
|
+
description: 'Output display level ' \
|
258
|
+
"(#{DISPLAY_LEVEL_BASE} to #{DISPLAY_LEVEL_MAX} " \
|
259
|
+
'[data, +context, +info])',
|
251
260
|
env_var: 'MDE_DISPLAY_LEVEL',
|
252
261
|
long_name: 'display-level',
|
253
262
|
opt_name: 'display_level',
|
254
263
|
procname: 'val_as_int'
|
255
264
|
},
|
265
|
+
{
|
266
|
+
arg_name: 'REGEX',
|
267
|
+
default: nil,
|
268
|
+
description: 'Exclude blocks with name matching',
|
269
|
+
env_var: 'MDE_EXCLUDE_BY_NAME_REGEX',
|
270
|
+
opt_name: 'exclude_by_name_regex',
|
271
|
+
procname: 'val_as_str'
|
272
|
+
},
|
273
|
+
{
|
274
|
+
arg_name: 'REGEX',
|
275
|
+
default: nil,
|
276
|
+
description: 'Exclude blocks with shell matching',
|
277
|
+
env_var: 'MDE_EXCLUDE_BY_SHELL_REGEX',
|
278
|
+
opt_name: 'exclude_by_shell_regex',
|
279
|
+
procname: 'val_as_str'
|
280
|
+
},
|
281
|
+
{
|
282
|
+
arg_name: 'BOOL',
|
283
|
+
default: true,
|
284
|
+
description: 'Hide all blocks of type "expect"',
|
285
|
+
env_var: 'MDE_EXCLUDE_EXPECT_BLOCKS',
|
286
|
+
opt_name: 'exclude_expect_blocks',
|
287
|
+
procname: 'val_as_bool'
|
288
|
+
},
|
289
|
+
{
|
290
|
+
arg_name: 'BOOL',
|
291
|
+
default: true,
|
292
|
+
description: 'Exclude blocks with name matching expression " \
|
293
|
+
"`block_name_hidden_match`',
|
294
|
+
env_var: 'MDE_HIDE_BLOCKS_BY_NAME',
|
295
|
+
opt_name: 'hide_blocks_by_name',
|
296
|
+
procname: 'val_as_bool'
|
297
|
+
},
|
256
298
|
{
|
257
299
|
arg_name: 'INT.1-',
|
258
300
|
default: 32,
|
@@ -267,7 +309,6 @@ task :update_menu_yml do
|
|
267
309
|
default: MarkdownExec::BIN_NAME,
|
268
310
|
description: 'Name prefix for stdout files',
|
269
311
|
env_var: 'MDE_LOGGED_STDOUT_FILENAME_PREFIX',
|
270
|
-
# long_name: 'logged-stdout-filename-prefix',
|
271
312
|
opt_name: 'logged_stdout_filename_prefix',
|
272
313
|
procname: 'val_as_str'
|
273
314
|
},
|
@@ -276,7 +317,6 @@ task :update_menu_yml do
|
|
276
317
|
default: false,
|
277
318
|
description: 'Display document name in block selection menu',
|
278
319
|
env_var: 'MDE_MENU_BLOCKS_WITH_DOCNAME',
|
279
|
-
# long_name: 'menu-blocks-with-docname',
|
280
320
|
opt_name: 'menu_blocks_with_docname',
|
281
321
|
procname: 'val_as_bool'
|
282
322
|
},
|
@@ -285,10 +325,25 @@ task :update_menu_yml do
|
|
285
325
|
default: false,
|
286
326
|
description: 'Display headings (levels 1,2,3) in block selection menu',
|
287
327
|
env_var: 'MDE_MENU_BLOCKS_WITH_HEADINGS',
|
288
|
-
# long_name: 'menu-blocks-with-headings',
|
289
328
|
opt_name: 'menu_blocks_with_headings',
|
290
329
|
procname: 'val_as_bool'
|
291
330
|
},
|
331
|
+
{
|
332
|
+
arg_name: 'BOOL',
|
333
|
+
default: true,
|
334
|
+
description: 'Display Exit option at top of menu',
|
335
|
+
env_var: 'MDE_MENU_EXIT_AT_TOP',
|
336
|
+
opt_name: 'menu_exit_at_top',
|
337
|
+
procname: 'val_as_bool'
|
338
|
+
},
|
339
|
+
{
|
340
|
+
arg_name: 'BOOL',
|
341
|
+
default: true,
|
342
|
+
description: 'Display Exit option in menu',
|
343
|
+
env_var: 'MDE_MENU_WITH_EXIT',
|
344
|
+
opt_name: 'menu_with_exit',
|
345
|
+
procname: 'val_as_bool'
|
346
|
+
},
|
292
347
|
{
|
293
348
|
arg_name: 'BOOL',
|
294
349
|
default: false,
|
@@ -298,6 +353,14 @@ task :update_menu_yml do
|
|
298
353
|
opt_name: 'output_execution_summary',
|
299
354
|
procname: 'val_as_bool'
|
300
355
|
},
|
356
|
+
{
|
357
|
+
arg_name: 'BOOL',
|
358
|
+
default: false,
|
359
|
+
description: 'Output saved script filename at end of execution',
|
360
|
+
env_var: 'MDE_OUTPUT_SAVED_SCRIPT_FILENAME',
|
361
|
+
opt_name: 'output_saved_script_filename',
|
362
|
+
procname: 'val_as_bool'
|
363
|
+
},
|
301
364
|
{
|
302
365
|
arg_name: 'BOOL',
|
303
366
|
default: false,
|
@@ -339,7 +402,6 @@ task :update_menu_yml do
|
|
339
402
|
default: 0o755,
|
340
403
|
description: 'chmod for saved scripts',
|
341
404
|
env_var: 'MDE_SAVED_SCRIPT_CHMOD',
|
342
|
-
# long_name: 'saved-script-chmod',
|
343
405
|
opt_name: 'saved_script_chmod',
|
344
406
|
procname: 'val_as_int'
|
345
407
|
},
|
@@ -348,7 +410,6 @@ task :update_menu_yml do
|
|
348
410
|
default: MarkdownExec::BIN_NAME,
|
349
411
|
description: 'Name prefix for saved scripts',
|
350
412
|
env_var: 'MDE_SAVED_SCRIPT_FILENAME_PREFIX',
|
351
|
-
# long_name: 'saved-script-filename-prefix',
|
352
413
|
opt_name: 'saved_script_filename_prefix',
|
353
414
|
procname: 'val_as_str'
|
354
415
|
},
|
@@ -366,7 +427,6 @@ task :update_menu_yml do
|
|
366
427
|
default: 'mde_*.sh',
|
367
428
|
description: 'Glob matching saved scripts',
|
368
429
|
env_var: 'MDE_SAVED_SCRIPT_GLOB',
|
369
|
-
# long_name: 'saved-script-glob',
|
370
430
|
opt_name: 'saved_script_glob',
|
371
431
|
procname: 'val_as_str'
|
372
432
|
},
|
@@ -384,11 +444,25 @@ task :update_menu_yml do
|
|
384
444
|
default: 'mde_*.out.txt',
|
385
445
|
description: 'Glob matching saved outputs',
|
386
446
|
env_var: 'MDE_SAVED_STDOUT_GLOB',
|
387
|
-
# long_name: 'saved-stdout-glob',
|
388
447
|
opt_name: 'saved_stdout_glob',
|
389
448
|
procname: 'val_as_str'
|
390
449
|
},
|
391
|
-
|
450
|
+
{
|
451
|
+
arg_name: 'REGEX',
|
452
|
+
default: nil,
|
453
|
+
description: 'Select blocks with name matching',
|
454
|
+
env_var: 'MDE_SELECT_BY_NAME_REGEX',
|
455
|
+
opt_name: 'select_by_name_regex',
|
456
|
+
procname: 'val_as_str'
|
457
|
+
},
|
458
|
+
{
|
459
|
+
arg_name: 'REGEX',
|
460
|
+
default: nil,
|
461
|
+
description: 'Select blocks with shell matching',
|
462
|
+
env_var: 'MDE_SELECT_BY_SHELL_REGEX',
|
463
|
+
opt_name: 'select_by_shell_regex',
|
464
|
+
procname: 'val_as_str'
|
465
|
+
},
|
392
466
|
{
|
393
467
|
default: '^[\(\[].*[\)\]]$',
|
394
468
|
description: 'Pattern for blocks to hide from user-selection',
|
@@ -415,13 +489,13 @@ task :update_menu_yml do
|
|
415
489
|
procname: 'val_as_str'
|
416
490
|
},
|
417
491
|
{
|
418
|
-
default: '<(?<full>(?<type>\$)?(?<name>[A-Za-
|
492
|
+
default: '<(?<full>(?<type>\$)?(?<name>[A-Za-z_\-\.\w]+))',
|
419
493
|
env_var: 'MDE_BLOCK_STDIN_SCAN',
|
420
494
|
opt_name: 'block_stdin_scan',
|
421
495
|
procname: 'val_as_str'
|
422
496
|
},
|
423
497
|
{
|
424
|
-
default: '>(?<full>(?<type>\$)?(?<name>[A-Za-
|
498
|
+
default: '>(?<full>(?<type>\$)?(?<name>[A-Za-z_\-\.\w]+))',
|
425
499
|
env_var: 'MDE_BLOCK_STDOUT_SCAN',
|
426
500
|
opt_name: 'block_stdout_scan',
|
427
501
|
procname: 'val_as_str'
|
@@ -439,7 +513,7 @@ task :update_menu_yml do
|
|
439
513
|
procname: 'val_as_str'
|
440
514
|
},
|
441
515
|
{
|
442
|
-
default: '^`{3,}(?<shell>[^`\s]*) *(?<
|
516
|
+
default: '^`{3,}(?<shell>[^`\s]*) *:?(?<name>[^\s]*) *(?<rest>.*) *$',
|
443
517
|
env_var: 'MDE_FENCED_START_EX_MATCH',
|
444
518
|
opt_name: 'fenced_start_ex_match',
|
445
519
|
procname: 'val_as_str'
|
@@ -462,6 +536,12 @@ task :update_menu_yml do
|
|
462
536
|
opt_name: 'heading3_match',
|
463
537
|
procname: 'val_as_str'
|
464
538
|
},
|
539
|
+
{
|
540
|
+
default: '^ *@import (.+)$',
|
541
|
+
env_var: 'MDE_IMPORT_PATTERN',
|
542
|
+
opt_name: 'import_pattern',
|
543
|
+
procname: 'val_as_str'
|
544
|
+
},
|
465
545
|
{
|
466
546
|
default: '*.[Mm][Dd]',
|
467
547
|
env_var: 'MDE_MD_FILENAME_GLOB',
|
@@ -612,18 +692,12 @@ task :update_menu_yml do
|
|
612
692
|
env_var: 'MDE_OUTPUT_DIVIDER_COLOR',
|
613
693
|
opt_name: 'output_divider_color',
|
614
694
|
procname: 'val_as_str'
|
615
|
-
# },
|
616
|
-
# {
|
617
|
-
# default: '',
|
618
|
-
# description: '',
|
619
|
-
# env_var: 'MDE_PROMPT_',
|
620
|
-
# opt_name: 'prompt_',
|
621
|
-
# procname: 'val_as_str'
|
622
695
|
}
|
623
696
|
]
|
624
697
|
|
625
698
|
File.write(MENU_YML,
|
626
|
-
"# #{MarkdownExec::APP_NAME} - #{MarkdownExec::APP_DESC}
|
699
|
+
"# #{MarkdownExec::APP_NAME} - #{MarkdownExec::APP_DESC} " \
|
700
|
+
"(#{MarkdownExec::VERSION})\n" +
|
627
701
|
menu_options.to_yaml)
|
628
702
|
puts `stat #{MENU_YML}`
|
629
703
|
end
|
@@ -640,7 +714,10 @@ def update_tab_completion(target)
|
|
640
714
|
svh[:compreply] = CLI.value_for_cli(svh[:default]) if svh[:compreply].nil?
|
641
715
|
end.tap_inspect name: :svhs, type: :yaml
|
642
716
|
|
643
|
-
File.write target,
|
717
|
+
File.write target,
|
718
|
+
ERB.new(File.read(filespec = File.join(BF,
|
719
|
+
'tab_completion.sh.erb')))
|
720
|
+
.result(binding)
|
644
721
|
puts `stat #{filespec}`
|
645
722
|
end
|
646
723
|
|
data/bin/tab_completion.sh
CHANGED
@@ -13,7 +13,7 @@ __filedirs_all()
|
|
13
13
|
}
|
14
14
|
|
15
15
|
_mde_echo_version() {
|
16
|
-
echo "1.3.
|
16
|
+
echo "1.3.3.1"
|
17
17
|
}
|
18
18
|
|
19
19
|
_mde() {
|
@@ -138,4 +138,4 @@ _mde() {
|
|
138
138
|
|
139
139
|
complete -o filenames -o nospace -F _mde mde
|
140
140
|
# _mde_echo_version
|
141
|
-
# echo "Updated:
|
141
|
+
# echo "Updated: 2023-10-04 01:23:26 UTC"
|
@@ -0,0 +1,115 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# encoding=utf-8
|
5
|
+
|
6
|
+
# version 2023-10-03
|
7
|
+
|
8
|
+
require 'bundler/setup'
|
9
|
+
Bundler.require(:default)
|
10
|
+
|
11
|
+
##
|
12
|
+
# The CachedNestedFileReader class provides functionality to read file lines with the ability
|
13
|
+
# to process '#import filename' directives. When such a directive is encountered in a file,
|
14
|
+
# the corresponding 'filename' is read and its contents are inserted at that location.
|
15
|
+
# This class caches read files to avoid re-reading the same file multiple times.
|
16
|
+
# It allows clients to read lines with or without providing a block.
|
17
|
+
#
|
18
|
+
class CachedNestedFileReader
|
19
|
+
def initialize(import_pattern: /^ *#import (.+)$/)
|
20
|
+
@file_cache = {}
|
21
|
+
@import_pattern = import_pattern
|
22
|
+
end
|
23
|
+
|
24
|
+
def readlines(filename, &block)
|
25
|
+
if @file_cache.key?(filename)
|
26
|
+
@file_cache[filename].each(&block) if block_given?
|
27
|
+
return @file_cache[filename]
|
28
|
+
end
|
29
|
+
|
30
|
+
directory_path = File.dirname(filename)
|
31
|
+
lines = File.readlines(filename, chomp: true)
|
32
|
+
processed_lines = []
|
33
|
+
|
34
|
+
lines.each do |line|
|
35
|
+
if (match = line.match(@import_pattern))
|
36
|
+
included_file_path = if match[1].strip.match %r{^/}
|
37
|
+
match[1].strip
|
38
|
+
else
|
39
|
+
File.join(directory_path, match[1].strip)
|
40
|
+
end
|
41
|
+
processed_lines += readlines(included_file_path, &block)
|
42
|
+
else
|
43
|
+
processed_lines.push(line)
|
44
|
+
yield line if block_given?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
@file_cache[filename] = processed_lines
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def fetch_lines(filename)
|
54
|
+
@fetch_lines_cache[filename] ||= File.readlines(filename, chomp: true)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
if $PROGRAM_NAME == __FILE__
|
59
|
+
require 'minitest/autorun'
|
60
|
+
require 'tempfile'
|
61
|
+
|
62
|
+
##
|
63
|
+
# The CachedNestedFileReaderTest class provides testing for
|
64
|
+
# the CachedNestedFileReader class.
|
65
|
+
#
|
66
|
+
class CachedNestedFileReaderTest < Minitest::Test
|
67
|
+
def setup
|
68
|
+
@file2 = Tempfile.new('test2.txt')
|
69
|
+
@file2.write("ImportedLine1\nImportedLine2")
|
70
|
+
@file2.rewind
|
71
|
+
|
72
|
+
@file1 = Tempfile.new('test1.txt')
|
73
|
+
@file1.write("Line1\nLine2\n #insert #{@file2.path}\nLine3")
|
74
|
+
@file1.rewind
|
75
|
+
# binding.pry
|
76
|
+
@reader = CachedNestedFileReader.new(import_pattern: /^ *#insert (.+)$/)
|
77
|
+
end
|
78
|
+
|
79
|
+
def teardown
|
80
|
+
@file1.close
|
81
|
+
@file1.unlink
|
82
|
+
|
83
|
+
@file2.close
|
84
|
+
@file2.unlink
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_readlines_without_imports
|
88
|
+
result = []
|
89
|
+
@reader.readlines(@file2.path) { |line| result << line }
|
90
|
+
assert_equal %w[ImportedLine1 ImportedLine2], result
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_readlines_with_imports
|
94
|
+
result = []
|
95
|
+
@reader.readlines(@file1.path) { |line| result << line }
|
96
|
+
assert_equal %w[Line1 Line2 ImportedLine1 ImportedLine2 Line3], result
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_caching_functionality
|
100
|
+
# First read
|
101
|
+
result1 = []
|
102
|
+
@reader.readlines(@file2.path) { |line| result1 << line }
|
103
|
+
|
104
|
+
# Simulate file content change
|
105
|
+
@file2.reopen(@file2.path, 'w') { |f| f.write('ChangedLine') }
|
106
|
+
|
107
|
+
# Second read (should read from cache, not the changed file)
|
108
|
+
result2 = []
|
109
|
+
@reader.readlines(@file2.path) { |line| result2 << line }
|
110
|
+
|
111
|
+
assert_equal result1, result2
|
112
|
+
assert_equal %w[ImportedLine1 ImportedLine2], result2
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
data/lib/colorize.rb
CHANGED
data/lib/env.rb
CHANGED
data/lib/env_opts.rb
CHANGED
@@ -11,6 +11,7 @@ include Tap #; tap_config
|
|
11
11
|
# option to cast input values
|
12
12
|
# value priority: default < environment < argument
|
13
13
|
#
|
14
|
+
# :reek:TooManyMethods
|
14
15
|
class EnvOpts
|
15
16
|
attr_reader :opts, :values
|
16
17
|
|
@@ -27,50 +28,47 @@ class EnvOpts
|
|
27
28
|
# add options to menu
|
28
29
|
# calculate help text
|
29
30
|
#
|
31
|
+
# :reek:NestedIterators
|
30
32
|
def add_options(opts_raw)
|
31
33
|
return self if opts_raw.nil?
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
+
help_rows = opts_raw.map do |key, opt_raw|
|
36
|
+
opt_name = key_name_to_option_name(key)
|
35
37
|
|
36
|
-
# set_per_options(
|
37
|
-
@opts[
|
38
|
-
set_key_value_as_cast
|
39
|
-
|
40
|
-
set_key_value_per_environment_as_cast(key2, opt_raw)
|
38
|
+
# set_per_options(opt_name, opt_raw)
|
39
|
+
@opts[opt_name] = (opt_raw ||= {})
|
40
|
+
set_key_value_as_cast(opt_name, EnvOpts.optdefault(opt_raw))
|
41
|
+
set_key_value_per_environment_as_cast(opt_name, opt_raw)
|
41
42
|
|
42
43
|
[
|
43
|
-
[20, '-', "--#{
|
44
|
-
[16, '-',
|
45
|
-
|
46
|
-
|
44
|
+
[20, '-', "--#{opt_name}"],
|
45
|
+
[16, '-',
|
46
|
+
if @opts[opt_name][:env].present?
|
47
|
+
option_name_to_environment_name(opt_name, @opts[opt_name])
|
48
|
+
else
|
49
|
+
''
|
50
|
+
end],
|
51
|
+
# [24, '-', get_environment_value_from_option(opt_name, @opts[opt_name])],
|
52
|
+
[24, '-', @opts[opt_name][:default]],
|
47
53
|
[6, '-', if (fixed = opt_raw.fetch(:fixed, nil)).nil?
|
48
|
-
":#{option_cast(@opts[
|
54
|
+
":#{option_cast(@opts[opt_name])}"
|
49
55
|
else
|
50
56
|
fixed.to_s
|
51
57
|
end]
|
52
58
|
]
|
53
|
-
end
|
59
|
+
end
|
54
60
|
|
55
|
-
max_widths =
|
56
|
-
|
57
|
-
[memo[
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
[format("%#{c0[1]}#{max_widths[0]}s", c0[2]),
|
66
|
-
format("%#{c1[1]}#{max_widths[1]}s", c1[2]),
|
67
|
-
format("%#{c2[1]}#{max_widths[2]}s", c2[2]),
|
68
|
-
format("%#{c3[1]}#{max_widths[3]}s", c3[2])]
|
69
|
-
end.map do |row|
|
70
|
-
row.join(' ')
|
61
|
+
max_widths = help_rows.reduce([0, 0, 0, 0]) do |memo, vals|
|
62
|
+
vals.map.with_index do |val, ind|
|
63
|
+
[memo[ind], val[2].to_s.length].max
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
@values['help'] = help_rows.map do |row|
|
68
|
+
row.map.with_index do |cell, ind|
|
69
|
+
format("%#{cell[1]}#{max_widths[ind]}s", cell[2])
|
70
|
+
end.join(' ')
|
71
71
|
end.join("\n")
|
72
|
-
@opts.tap_inspect '@opts'
|
73
|
-
@values.tap_inspect '@values'
|
74
72
|
|
75
73
|
self
|
76
74
|
end
|
@@ -98,7 +96,8 @@ class EnvOpts
|
|
98
96
|
arg = argv.fetch(args_ind, '') #.tap_inspect 'argument', source: 'EnvOpts'
|
99
97
|
if arg.start_with? '--'
|
100
98
|
opt_name = arg[2..-1] #.tap_inspect 'opt_name', source: 'EnvOpts'
|
101
|
-
args_consumed = consume_arguments(opt_name,
|
99
|
+
args_consumed = consume_arguments(opt_name,
|
100
|
+
argv.fetch(args_ind + 1, nil))
|
102
101
|
end
|
103
102
|
|
104
103
|
if args_consumed.zero?
|
@@ -116,37 +115,42 @@ class EnvOpts
|
|
116
115
|
|
117
116
|
args_ind += args_consumed
|
118
117
|
end
|
119
|
-
@opts.tap_inspect '@opts'
|
120
|
-
@values.tap_inspect '@values'
|
121
118
|
|
122
119
|
self
|
123
120
|
end
|
124
121
|
|
125
122
|
# set option current values per environment values
|
126
123
|
#
|
127
|
-
def
|
124
|
+
def options_per_environment_as_cast(opts_raw)
|
128
125
|
return self if opts_raw.nil?
|
129
126
|
|
130
127
|
opts_raw.each do |key, opt_raw|
|
131
|
-
set_key_value_per_environment_as_cast(key_name_to_option_name(key),
|
128
|
+
set_key_value_per_environment_as_cast(key_name_to_option_name(key),
|
129
|
+
opt_raw)
|
132
130
|
end
|
133
|
-
@opts.tap_inspect '@opts'
|
134
131
|
|
135
132
|
self
|
136
133
|
end
|
137
134
|
|
135
|
+
# symbol name to option name
|
136
|
+
# option names use hyphens
|
137
|
+
#
|
138
|
+
def self.symbol_name_to_option_name(name)
|
139
|
+
name.to_s.gsub('_', '-') #.tap_inspect
|
140
|
+
end
|
141
|
+
|
138
142
|
private
|
139
143
|
|
140
144
|
# convert key name or symbol to an option name
|
141
145
|
#
|
142
146
|
def key_name_to_option_name(key)
|
143
|
-
(key.is_a?(Symbol) ? symbol_name_to_option_name(key) : key) #.tap_inspect
|
147
|
+
(key.is_a?(Symbol) ? EnvOpts.symbol_name_to_option_name(key) : key) #.tap_inspect
|
144
148
|
end
|
145
149
|
|
146
150
|
# get cast of environment variable
|
147
151
|
#
|
148
152
|
def option_cast(opt_raw)
|
149
|
-
(opt_raw[:cast].present? ? opt_raw[:cast].to_s : 'to_s')
|
153
|
+
(opt_raw[:cast].present? ? opt_raw[:cast].to_s : 'to_s')
|
150
154
|
end
|
151
155
|
|
152
156
|
# update value for named option
|
@@ -177,14 +181,13 @@ class EnvOpts
|
|
177
181
|
# read and write options using the option name as a method
|
178
182
|
#
|
179
183
|
def method_missing(method_name, *args)
|
180
|
-
method_name.tap_inspect 'method_name'
|
181
184
|
if method_name.to_s.end_with?('=')
|
182
185
|
value = args.first
|
183
186
|
name = method_name_to_option_name(method_name.to_s[0..-2])
|
184
187
|
set_key_value_as_cast(name, value)
|
185
188
|
else
|
186
189
|
@values[method_name_to_option_name(method_name)]
|
187
|
-
end
|
190
|
+
end #.tap_inspect "ref #{method_name}", source: 'EnvOpts'
|
188
191
|
end
|
189
192
|
|
190
193
|
# option name to environment name
|
@@ -196,23 +199,24 @@ class EnvOpts
|
|
196
199
|
"#{@values['env-prefix']}#{opt_name.upcase.gsub('-', '_')}"
|
197
200
|
else
|
198
201
|
env_name
|
199
|
-
end
|
202
|
+
end
|
200
203
|
end
|
201
204
|
|
202
205
|
# get environment value from option
|
203
206
|
#
|
204
207
|
def get_environment_value_from_option(opt_name, opt_raw)
|
205
|
-
ENV.fetch(option_name_to_environment_name(opt_name, opt_raw),
|
208
|
+
ENV.fetch(option_name_to_environment_name(opt_name, opt_raw),
|
209
|
+
nil)
|
206
210
|
end
|
207
211
|
|
208
212
|
# option names are available as methods
|
209
213
|
#
|
214
|
+
# :reek:BooleanParameter
|
210
215
|
def respond_to_missing?(method_name, include_private = false)
|
211
216
|
(@opts.keys.include?(method_name_to_option_name(method_name)) || super)
|
212
217
|
end
|
213
218
|
|
214
219
|
def set_key_value_as_cast(key, value)
|
215
|
-
[key, value].tap_inspect 'key, value'
|
216
220
|
opt = @opts[key]
|
217
221
|
set_key_value_raw(key, (opt[:cast] ? value.send(opt[:cast]) : value))
|
218
222
|
end
|
@@ -220,25 +224,19 @@ class EnvOpts
|
|
220
224
|
# set key value_per environment as cast
|
221
225
|
#
|
222
226
|
def set_key_value_per_environment_as_cast(key, opt_raw)
|
223
|
-
key.tap_inspect 'key'
|
224
|
-
opt_raw.tap_inspect 'opt_raw'
|
225
227
|
return if opt_raw[:env].nil?
|
226
228
|
|
227
|
-
value = get_environment_value_from_option(key, opt_raw)
|
228
|
-
|
229
|
+
value = get_environment_value_from_option(key, opt_raw)
|
230
|
+
|
231
|
+
return unless value
|
232
|
+
|
233
|
+
set_key_value_as_cast(key,
|
234
|
+
opt_raw[:cast] ? value.send(opt_raw[:cast]) : value)
|
229
235
|
end
|
230
236
|
|
231
237
|
# set key value (raw)
|
232
238
|
#
|
233
239
|
def set_key_value_raw(key, value)
|
234
|
-
[key, value].tap_inspect 'key, value'
|
235
240
|
@values[key] = value
|
236
241
|
end
|
237
|
-
|
238
|
-
# symbol name to option name
|
239
|
-
# option names use hyphens
|
240
|
-
#
|
241
|
-
def symbol_name_to_option_name(name)
|
242
|
-
name.to_s.gsub('_', '-') #.tap_inspect
|
243
|
-
end
|
244
242
|
end
|