markdown_exec 1.7 → 1.8
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 +5 -2
- data/Gemfile.lock +1 -1
- data/Rakefile +1 -0
- data/bin/tab_completion.sh +19 -3
- data/examples/colors.md +48 -0
- data/examples/include.md +11 -4
- data/examples/opts.md +7 -0
- data/lib/ansi_formatter.rb +161 -0
- data/lib/directory_searcher.rb +239 -0
- data/lib/env.rb +1 -2
- data/lib/hash_delegator.rb +138 -51
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +66 -29
- data/lib/mdoc.rb +148 -33
- data/lib/menu.src.yml +94 -17
- data/lib/menu.yml +86 -18
- data/lib/option_value.rb +2 -4
- data/lib/regexp.rb +1 -2
- data/lib/saved_assets.rb +2 -4
- data/lib/saved_files_matcher.rb +3 -7
- data/lib/tap.rb +2 -5
- metadata +5 -2
data/lib/hash_delegator.rb
CHANGED
@@ -18,6 +18,7 @@ require_relative 'block_label'
|
|
18
18
|
require_relative 'block_types'
|
19
19
|
require_relative 'cached_nested_file_reader'
|
20
20
|
require_relative 'constants'
|
21
|
+
require_relative 'directory_searcher'
|
21
22
|
require_relative 'exceptions'
|
22
23
|
require_relative 'fcb'
|
23
24
|
require_relative 'filter'
|
@@ -34,6 +35,56 @@ class String
|
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
38
|
+
# This module provides methods for compacting and converting data structures.
|
39
|
+
module CompactionHelpers
|
40
|
+
# Converts an array of key-value pairs into a hash, applying compaction to the values.
|
41
|
+
# Each value is processed by `compact_hash` to remove ineligible elements.
|
42
|
+
#
|
43
|
+
# @param array [Array] The array of key-value pairs to be converted.
|
44
|
+
# @return [Hash] A hash with keys from the array and compacted values.
|
45
|
+
def compact_and_convert_array_to_hash(array)
|
46
|
+
array.transform_values do |value|
|
47
|
+
compact_hash(value)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Compacts a hash by removing ineligible elements.
|
52
|
+
# It filters out nil, empty arrays, empty hashes, and empty strings from its values.
|
53
|
+
# It also removes entries with :random as the key.
|
54
|
+
#
|
55
|
+
# @param hash [Hash] The hash to be compacted.
|
56
|
+
# @return [Hash] A compacted version of the input hash.
|
57
|
+
def compact_hash(hash)
|
58
|
+
hash.map do |key, value|
|
59
|
+
next if value_ineligible?(value) || key == :random
|
60
|
+
|
61
|
+
[key, value]
|
62
|
+
end.compact.to_h
|
63
|
+
end
|
64
|
+
|
65
|
+
# Converts a hash into another hash with indexed keys, applying compaction to the values.
|
66
|
+
# The keys are indexed, and the values are compacted using `compact_and_convert_array_to_hash`.
|
67
|
+
#
|
68
|
+
# @param hash [Hash] The hash to be converted and compacted.
|
69
|
+
# @return [Hash] A hash with indexed keys and the compacted original values.
|
70
|
+
def compact_and_index_hash(hash)
|
71
|
+
compact_and_convert_array_to_hash(hash.map.with_index do |value, index|
|
72
|
+
[index, value]
|
73
|
+
end.to_h)
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
# Determines if a value is ineligible for inclusion in a compacted hash.
|
79
|
+
# Ineligible values are nil, empty arrays, empty hashes, and empty strings.
|
80
|
+
#
|
81
|
+
# @param value [Object] The value to be checked.
|
82
|
+
# @return [Boolean] True if the value is ineligible, false otherwise.
|
83
|
+
def value_ineligible?(value)
|
84
|
+
[nil, [], {}, ''].include?(value)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
37
88
|
module MarkdownExec
|
38
89
|
class DebugHelper
|
39
90
|
# Class-level variable to store history of printed messages
|
@@ -51,12 +102,16 @@ module MarkdownExec
|
|
51
102
|
end
|
52
103
|
|
53
104
|
class HashDelegator
|
54
|
-
attr_accessor :run_state
|
105
|
+
attr_accessor :most_recent_loaded_filename, :pass_args, :run_state
|
106
|
+
|
107
|
+
include CompactionHelpers
|
55
108
|
|
56
109
|
def initialize(delegate_object = {})
|
57
110
|
@delegate_object = delegate_object
|
58
111
|
@prompt = tty_prompt_without_disabled_symbol
|
59
112
|
|
113
|
+
@most_recent_loaded_filename = nil
|
114
|
+
@pass_args = []
|
60
115
|
@run_state = OpenStruct.new(
|
61
116
|
link_history: []
|
62
117
|
)
|
@@ -267,6 +322,25 @@ module MarkdownExec
|
|
267
322
|
true
|
268
323
|
end
|
269
324
|
|
325
|
+
def runtime_exception(exception_sym, name, items)
|
326
|
+
if @delegate_object[exception_sym] != 0
|
327
|
+
data = { name: name, detail: items.join(', ') }
|
328
|
+
warn(
|
329
|
+
format(
|
330
|
+
@delegate_object.fetch(:exception_format_name, "\n%{name}"),
|
331
|
+
data
|
332
|
+
).send(@delegate_object.fetch(:exception_color_name, :red)) +
|
333
|
+
format(
|
334
|
+
@delegate_object.fetch(:exception_format_detail, " - %{detail}\n"),
|
335
|
+
data
|
336
|
+
).send(@delegate_object.fetch(:exception_color_detail, :yellow))
|
337
|
+
)
|
338
|
+
end
|
339
|
+
return unless (@delegate_object[exception_sym]).positive?
|
340
|
+
|
341
|
+
exit @delegate_object[exception_sym]
|
342
|
+
end
|
343
|
+
|
270
344
|
# Collects required code lines based on the selected block and the delegate object's configuration.
|
271
345
|
# If the block type is VARS, it also sets environment variables based on the block's content.
|
272
346
|
#
|
@@ -274,13 +348,22 @@ module MarkdownExec
|
|
274
348
|
# @param selected [Hash] The selected block.
|
275
349
|
# @return [Array<String>] Required code blocks as an array of lines.
|
276
350
|
def collect_required_code_lines(mdoc, selected)
|
277
|
-
if selected[:shell] == BlockType::VARS
|
278
|
-
set_environment_variables(selected)
|
279
|
-
end
|
351
|
+
set_environment_variables(selected) if selected[:shell] == BlockType::VARS
|
280
352
|
|
281
353
|
required = mdoc.collect_recursively_required_code(
|
282
|
-
@delegate_object[:block_name],
|
354
|
+
@delegate_object[:block_name],
|
355
|
+
label_format_above: @delegate_object[:shell_code_label_format_above],
|
356
|
+
label_format_below: @delegate_object[:shell_code_label_format_below]
|
283
357
|
)
|
358
|
+
if required[:unmet_dependencies].present?
|
359
|
+
warn format_and_highlight_dependencies(required[:dependencies],
|
360
|
+
highlight: required[:unmet_dependencies])
|
361
|
+
runtime_exception(:runtime_exception_error_level,
|
362
|
+
'unmet_dependencies, flag: runtime_exception_error_level', required[:unmet_dependencies])
|
363
|
+
elsif true
|
364
|
+
warn format_and_highlight_dependencies(required[:dependencies],
|
365
|
+
highlight: [@delegate_object[:block_name]])
|
366
|
+
end
|
284
367
|
read_required_blocks_from_temp_file + required[:code]
|
285
368
|
end
|
286
369
|
|
@@ -489,11 +572,11 @@ module MarkdownExec
|
|
489
572
|
fcb.derive_title_from_body
|
490
573
|
end
|
491
574
|
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
!current_item&.fetch(:oname).present?
|
575
|
+
# delete the current line if it is empty and the previous is also empty
|
576
|
+
def delete_consecutive_blank_lines!(blocks_menu)
|
577
|
+
blocks_menu.process_and_conditionally_delete! do |prev_item, current_item, _next_item|
|
578
|
+
prev_item&.fetch(:chrome, nil) && !prev_item&.fetch(:oname).present? &&
|
579
|
+
current_item&.fetch(:chrome, nil) && !current_item&.fetch(:oname).present?
|
497
580
|
end
|
498
581
|
end
|
499
582
|
|
@@ -575,8 +658,8 @@ module MarkdownExec
|
|
575
658
|
#
|
576
659
|
# @param required_lines [Array<String>] The lines of code to be executed.
|
577
660
|
# @param selected [FCB] The selected functional code block object.
|
578
|
-
def execute_approved_block(required_lines = [],
|
579
|
-
set_script_block_name(selected)
|
661
|
+
def execute_approved_block(required_lines = [], _selected = FCB.new)
|
662
|
+
# set_script_block_name(selected)
|
580
663
|
write_command_file_if_needed(required_lines)
|
581
664
|
format_and_execute_command(required_lines)
|
582
665
|
post_execution_process
|
@@ -596,8 +679,7 @@ module MarkdownExec
|
|
596
679
|
formatted_command = lines.flatten.join("\n")
|
597
680
|
@fout.fout fetch_color(data_sym: :script_execution_head,
|
598
681
|
color_sym: :script_execution_frame_color)
|
599
|
-
command_execute(formatted_command,
|
600
|
-
args: @delegate_object.fetch(:s_pass_args, []))
|
682
|
+
command_execute(formatted_command, args: @pass_args)
|
601
683
|
@fout.fout fetch_color(data_sym: :script_execution_tail,
|
602
684
|
color_sym: :script_execution_frame_color)
|
603
685
|
end
|
@@ -722,12 +804,8 @@ module MarkdownExec
|
|
722
804
|
def handle_generic_block(mdoc, selected)
|
723
805
|
required_lines = collect_required_code_lines(mdoc, selected)
|
724
806
|
output_or_approval = @delegate_object[:output_script] || @delegate_object[:user_must_approve]
|
725
|
-
|
726
807
|
display_required_code(required_lines) if output_or_approval
|
727
|
-
|
728
808
|
allow_execution = @delegate_object[:user_must_approve] ? prompt_for_user_approval(required_lines) : true
|
729
|
-
|
730
|
-
@delegate_object[:s_ir_approve] = allow_execution
|
731
809
|
execute_approved_block(required_lines, selected) if allow_execution
|
732
810
|
|
733
811
|
LoadFileNextBlock.new(LoadFile::Reuse, '')
|
@@ -769,7 +847,7 @@ module MarkdownExec
|
|
769
847
|
# @return [LoadFileNextBlock] An instance indicating the next action for loading files.
|
770
848
|
def handle_opts_block(selected, tgt2 = nil)
|
771
849
|
data = YAML.load(selected[:body].join("\n"))
|
772
|
-
data.each do |key, value|
|
850
|
+
(data || []).each do |key, value|
|
773
851
|
update_delegate_and_target(key, value, tgt2)
|
774
852
|
if @delegate_object[:menu_opts_set_format].present?
|
775
853
|
print_formatted_option(key,
|
@@ -931,7 +1009,7 @@ module MarkdownExec
|
|
931
1009
|
# @return [Boolean, nil] True if values were modified, nil otherwise.
|
932
1010
|
def load_auto_blocks(all_blocks)
|
933
1011
|
block_name = @delegate_object[:document_load_opts_block_name]
|
934
|
-
unless block_name.present? && @
|
1012
|
+
unless block_name.present? && @most_recent_loaded_filename != @delegate_object[:filename]
|
935
1013
|
return
|
936
1014
|
end
|
937
1015
|
|
@@ -939,7 +1017,7 @@ module MarkdownExec
|
|
939
1017
|
return unless block
|
940
1018
|
|
941
1019
|
handle_opts_block(block, @delegate_object)
|
942
|
-
@
|
1020
|
+
@most_recent_loaded_filename = @delegate_object[:filename]
|
943
1021
|
true
|
944
1022
|
end
|
945
1023
|
|
@@ -999,7 +1077,7 @@ module MarkdownExec
|
|
999
1077
|
|
1000
1078
|
menu_blocks = mdoc.fcbs_per_options(@delegate_object)
|
1001
1079
|
add_menu_chrome_blocks!(menu_blocks)
|
1002
|
-
|
1080
|
+
delete_consecutive_blank_lines!(menu_blocks) if true ### compress empty lines
|
1003
1081
|
[all_blocks, menu_blocks, mdoc]
|
1004
1082
|
end
|
1005
1083
|
|
@@ -1028,9 +1106,9 @@ module MarkdownExec
|
|
1028
1106
|
end
|
1029
1107
|
|
1030
1108
|
def next_block_name_from_command_line_arguments
|
1031
|
-
return MenuControl::Repeat unless @delegate_object[:
|
1109
|
+
return MenuControl::Repeat unless @delegate_object[:input_cli_rest].present?
|
1032
1110
|
|
1033
|
-
@delegate_object[:block_name] = @delegate_object[:
|
1111
|
+
@delegate_object[:block_name] = @delegate_object[:input_cli_rest].pop
|
1034
1112
|
MenuControl::Fresh
|
1035
1113
|
end
|
1036
1114
|
|
@@ -1209,7 +1287,7 @@ module MarkdownExec
|
|
1209
1287
|
# Markdown document, obtain approval, and execute the chosen block of code.
|
1210
1288
|
#
|
1211
1289
|
# @return [Nil] Returns nil if no code block is selected or an error occurs.
|
1212
|
-
def select_approve_and_execute_block
|
1290
|
+
def select_approve_and_execute_block(_execute: true)
|
1213
1291
|
@menu_base_options = @delegate_object
|
1214
1292
|
repeat_menu = @menu_base_options[:block_name].present? ? MenuControl::Fresh : MenuControl::Repeat
|
1215
1293
|
load_file_next_block = LoadFileNextBlock.new(LoadFile::Reuse)
|
@@ -1225,9 +1303,21 @@ module MarkdownExec
|
|
1225
1303
|
@menu_base_options[:block_name] = @menu_state_block_name
|
1226
1304
|
@menu_state_filename = nil
|
1227
1305
|
@menu_state_block_name = nil
|
1228
|
-
|
1229
1306
|
@menu_user_clicked_back_link = false
|
1307
|
+
|
1230
1308
|
blocks_in_file, menu_blocks, mdoc = mdoc_menu_and_blocks_from_nested_files
|
1309
|
+
if @delegate_object[:dump_blocks_in_file]
|
1310
|
+
warn format_and_highlight_dependencies(
|
1311
|
+
compact_and_index_hash(blocks_in_file),
|
1312
|
+
label: 'blocks_in_file'
|
1313
|
+
)
|
1314
|
+
end
|
1315
|
+
if @delegate_object[:dump_menu_blocks]
|
1316
|
+
warn format_and_highlight_dependencies(
|
1317
|
+
compact_and_index_hash(menu_blocks),
|
1318
|
+
label: 'menu_blocks'
|
1319
|
+
)
|
1320
|
+
end
|
1231
1321
|
block_state = command_or_user_selected_block(blocks_in_file,
|
1232
1322
|
menu_blocks, default)
|
1233
1323
|
return if block_state.state == MenuState::EXIT
|
@@ -1238,6 +1328,10 @@ module MarkdownExec
|
|
1238
1328
|
# error_handler("Block not found -- #{opts[:block_name]}", { abort: true })
|
1239
1329
|
end
|
1240
1330
|
|
1331
|
+
if @delegate_object[:dump_selected_block]
|
1332
|
+
warn block_state.block.to_yaml.sub(/^(?:---\n)?/, "Block:\n")
|
1333
|
+
end
|
1334
|
+
|
1241
1335
|
load_file_next_block = approve_and_execute_block(block_state.block,
|
1242
1336
|
mdoc)
|
1243
1337
|
default = load_file_next_block.load_file == LoadFile::Load ? nil : @delegate_object[:block_name]
|
@@ -1469,11 +1563,15 @@ module MarkdownExec
|
|
1469
1563
|
)
|
1470
1564
|
|
1471
1565
|
block_menu = prepare_blocks_menu(menu_blocks)
|
1472
|
-
if block_menu.empty?
|
1473
|
-
|
1474
|
-
|
1566
|
+
return SelectedBlockMenuState.new(nil, MenuState::EXIT) if block_menu.empty?
|
1567
|
+
|
1568
|
+
# default value may not match if color is different from originating menu (opts changed while processing)
|
1569
|
+
selection_opts = if default && menu_blocks.map(&:dname).include?(default)
|
1570
|
+
@delegate_object.merge(default: default)
|
1571
|
+
else
|
1572
|
+
@delegate_object
|
1573
|
+
end
|
1475
1574
|
|
1476
|
-
selection_opts = default ? @delegate_object.merge(default: default) : @delegate_object
|
1477
1575
|
selection_opts.merge!(per_page: @delegate_object[:select_page_height])
|
1478
1576
|
|
1479
1577
|
selected_option = select_option_with_metadata(prompt_title, block_menu,
|
@@ -1540,7 +1638,8 @@ module MarkdownExec
|
|
1540
1638
|
c1 = if mdoc
|
1541
1639
|
mdoc.collect_recursively_required_code(
|
1542
1640
|
block_name,
|
1543
|
-
|
1641
|
+
label_format_above: @delegate_object[:shell_code_label_format_above],
|
1642
|
+
label_format_below: @delegate_object[:shell_code_label_format_below]
|
1544
1643
|
)[:code]
|
1545
1644
|
else
|
1546
1645
|
[]
|
@@ -1597,16 +1696,14 @@ if $PROGRAM_NAME == __FILE__
|
|
1597
1696
|
obj = {
|
1598
1697
|
output_execution_label_format: '',
|
1599
1698
|
output_execution_label_name_color: 'plain',
|
1600
|
-
output_execution_label_value_color: 'plain'
|
1601
|
-
s_pass_args: pigeon
|
1602
|
-
# shell: 'bash'
|
1699
|
+
output_execution_label_value_color: 'plain'
|
1603
1700
|
}
|
1604
1701
|
|
1605
1702
|
c = MarkdownExec::HashDelegator.new(obj)
|
1703
|
+
c.pass_args = pigeon
|
1606
1704
|
|
1607
1705
|
# Expect that method opts_command_execute is called with argument args having value pigeon
|
1608
1706
|
c.expects(:command_execute).with(
|
1609
|
-
# obj,
|
1610
1707
|
'',
|
1611
1708
|
args: pigeon
|
1612
1709
|
)
|
@@ -2279,8 +2376,6 @@ if $PROGRAM_NAME == __FILE__
|
|
2279
2376
|
assert_equal 'value2',
|
2280
2377
|
@hd.instance_variable_get(:@delegate_object)[:option2]
|
2281
2378
|
end
|
2282
|
-
|
2283
|
-
# Additional test cases can be added to cover more scenarios and edge cases.
|
2284
2379
|
end
|
2285
2380
|
|
2286
2381
|
# require 'stringio'
|
@@ -2348,8 +2443,6 @@ if $PROGRAM_NAME == __FILE__
|
|
2348
2443
|
result = @hd.history_state_partition
|
2349
2444
|
assert_equal({ unit: '', rest: '' }, result)
|
2350
2445
|
end
|
2351
|
-
|
2352
|
-
# Additional test cases can be added to cover more scenarios and edge cases.
|
2353
2446
|
end
|
2354
2447
|
|
2355
2448
|
class TestHashDelegatorHistoryStatePop < Minitest::Test
|
@@ -2376,8 +2469,6 @@ if $PROGRAM_NAME == __FILE__
|
|
2376
2469
|
ENV.fetch(MDE_HISTORY_ENV_NAME, nil)
|
2377
2470
|
assert_empty @hd.instance_variable_get(:@run_state).link_history
|
2378
2471
|
end
|
2379
|
-
|
2380
|
-
# Additional test cases can be added to cover more scenarios and edge cases.
|
2381
2472
|
end
|
2382
2473
|
|
2383
2474
|
class TestHashDelegatorHistoryStatePush < Minitest::Test
|
@@ -2410,8 +2501,6 @@ if $PROGRAM_NAME == __FILE__
|
|
2410
2501
|
{ block_name: 'selected_block',
|
2411
2502
|
filename: 'data.md' }
|
2412
2503
|
end
|
2413
|
-
|
2414
|
-
# Additional test cases can be added to cover more scenarios and edge cases.
|
2415
2504
|
end
|
2416
2505
|
|
2417
2506
|
class TestHashDelegatorIterBlocksFromNestedFiles < Minitest::Test
|
@@ -2447,32 +2536,30 @@ if $PROGRAM_NAME == __FILE__
|
|
2447
2536
|
class TestHashDelegatorLoadAutoBlocks < Minitest::Test
|
2448
2537
|
def setup
|
2449
2538
|
@hd = HashDelegator.new
|
2450
|
-
@hd.
|
2451
|
-
document_load_opts_block_name: 'load_block',
|
2452
|
-
s_most_recent_filename: 'old_file',
|
2453
|
-
filename: 'new_file'
|
2454
|
-
})
|
2455
|
-
@hd.stubs(:block_find).returns({}) # Assuming it returns a block
|
2539
|
+
@hd.stubs(:block_find).returns({})
|
2456
2540
|
@hd.stubs(:handle_opts_block)
|
2457
2541
|
end
|
2458
2542
|
|
2459
2543
|
def test_load_auto_blocks_with_new_filename
|
2544
|
+
@hd.instance_variable_set(:@delegate_object, {
|
2545
|
+
document_load_opts_block_name: 'load_block',
|
2546
|
+
filename: 'new_file'
|
2547
|
+
})
|
2460
2548
|
assert @hd.load_auto_blocks([])
|
2461
2549
|
end
|
2462
2550
|
|
2463
2551
|
def test_load_auto_blocks_with_same_filename
|
2464
2552
|
@hd.instance_variable_set(:@delegate_object, {
|
2465
2553
|
document_load_opts_block_name: 'load_block',
|
2466
|
-
s_most_recent_filename: 'new_file',
|
2467
2554
|
filename: 'new_file'
|
2468
2555
|
})
|
2556
|
+
@hd.instance_variable_set(:@most_recent_loaded_filename, 'new_file')
|
2469
2557
|
assert_nil @hd.load_auto_blocks([])
|
2470
2558
|
end
|
2471
2559
|
|
2472
2560
|
def test_load_auto_blocks_without_block_name
|
2473
2561
|
@hd.instance_variable_set(:@delegate_object, {
|
2474
2562
|
document_load_opts_block_name: nil,
|
2475
|
-
s_most_recent_filename: 'old_file',
|
2476
2563
|
filename: 'new_file'
|
2477
2564
|
})
|
2478
2565
|
assert_nil @hd.load_auto_blocks([])
|
data/lib/markdown_exec.rb
CHANGED
@@ -13,10 +13,12 @@ require 'tmpdir'
|
|
13
13
|
require 'tty-prompt'
|
14
14
|
require 'yaml'
|
15
15
|
|
16
|
+
require_relative 'ansi_formatter'
|
16
17
|
require_relative 'block_label'
|
17
18
|
require_relative 'cached_nested_file_reader'
|
18
19
|
require_relative 'cli'
|
19
20
|
require_relative 'colorize'
|
21
|
+
require_relative 'directory_searcher'
|
20
22
|
require_relative 'env'
|
21
23
|
require_relative 'exceptions'
|
22
24
|
require_relative 'fcb'
|
@@ -225,9 +227,9 @@ module MarkdownExec
|
|
225
227
|
|
226
228
|
## Executes the block specified in the options
|
227
229
|
#
|
228
|
-
def execute_block_with_error_handling
|
229
|
-
finalize_cli_argument_processing
|
230
|
-
@options[:
|
230
|
+
def execute_block_with_error_handling
|
231
|
+
finalize_cli_argument_processing
|
232
|
+
@options[:input_cli_rest] = @rest
|
231
233
|
execute_code_block_based_on_options(@options)
|
232
234
|
rescue FileMissingError
|
233
235
|
warn "File missing: #{$!}"
|
@@ -242,6 +244,7 @@ module MarkdownExec
|
|
242
244
|
|
243
245
|
simple_commands = {
|
244
246
|
doc_glob: -> { @fout.fout options[:md_filename_glob] },
|
247
|
+
list_blocks: -> { list_blocks },
|
245
248
|
list_default_yaml: -> { @fout.fout_list list_default_yaml },
|
246
249
|
list_docs: -> { @fout.fout_list files },
|
247
250
|
list_default_env: -> { @fout.fout_list list_default_env },
|
@@ -290,7 +293,7 @@ module MarkdownExec
|
|
290
293
|
|
291
294
|
## post-parse options configuration
|
292
295
|
#
|
293
|
-
def finalize_cli_argument_processing(rest)
|
296
|
+
def finalize_cli_argument_processing(rest = @rest)
|
294
297
|
## position 0: file or folder (optional)
|
295
298
|
#
|
296
299
|
if (pos = rest.shift)&.present?
|
@@ -340,9 +343,8 @@ module MarkdownExec
|
|
340
343
|
end
|
341
344
|
@option_parser.load
|
342
345
|
@option_parser.environment
|
343
|
-
|
344
|
-
|
345
|
-
@options[:s_pass_args] = ARGV[rest.count + 1..]
|
346
|
+
@rest = rest = @option_parser.parse!(arguments_for_mde)
|
347
|
+
@options.pass_args = ARGV[rest.count + 1..]
|
346
348
|
@options.merge(@options.run_state.to_h)
|
347
349
|
|
348
350
|
rest
|
@@ -356,25 +358,64 @@ module MarkdownExec
|
|
356
358
|
def lambda_for_procname(procname, options)
|
357
359
|
case procname
|
358
360
|
when 'debug'
|
359
|
-
|
361
|
+
->(value) {
|
360
362
|
tap_config value: value
|
361
363
|
}
|
362
364
|
when 'exit'
|
363
365
|
->(_) { exit }
|
366
|
+
|
367
|
+
when 'find'
|
368
|
+
->(value) {
|
369
|
+
# initialize_and_parse_cli_options
|
370
|
+
@fout.fout "Searching in: " \
|
371
|
+
"#{HashDelegator.new(@options).string_send_color(@options[:path], :menu_chrome_color)}"
|
372
|
+
searcher = DirectorySearcher.new(value, [@options[:path]])
|
373
|
+
|
374
|
+
@fout.fout 'In directory names'
|
375
|
+
@fout.fout AnsiFormatter.new(options).format_and_highlight_array(
|
376
|
+
searcher.search_in_directory_names, highlight: [value]
|
377
|
+
)
|
378
|
+
|
379
|
+
@fout.fout 'In file names'
|
380
|
+
@fout.fout AnsiFormatter.new(options).format_and_highlight_array(
|
381
|
+
searcher.search_in_file_names, highlight: [value]
|
382
|
+
).join("\n")
|
383
|
+
|
384
|
+
@fout.fout 'In file contents'
|
385
|
+
hash = searcher.search_in_file_contents
|
386
|
+
hash.each.with_index do |(key, v2), i1|
|
387
|
+
@fout.fout format('- %3.d: %s', i1 + 1, key)
|
388
|
+
@fout.fout AnsiFormatter.new(options).format_and_highlight_array(
|
389
|
+
v2.map { |nl| format('=%4.d: %s', nl.index, nl.line) },
|
390
|
+
highlight: [value]
|
391
|
+
)
|
392
|
+
end
|
393
|
+
exit
|
394
|
+
}
|
395
|
+
|
364
396
|
when 'help'
|
365
|
-
|
397
|
+
->(_) {
|
366
398
|
@fout.fout menu_help
|
367
399
|
exit
|
368
400
|
}
|
401
|
+
# when %w[who what where why how which when whom]
|
402
|
+
when 'how'
|
403
|
+
->(value) {
|
404
|
+
# value = 'color'
|
405
|
+
@fout.fout(list_default_yaml.select { |line| line.include? value })
|
406
|
+
exit
|
407
|
+
}
|
369
408
|
when 'path'
|
370
|
-
->(value) {
|
409
|
+
->(value) {
|
410
|
+
read_configuration_file!(options, value)
|
411
|
+
}
|
371
412
|
when 'show_config'
|
372
|
-
|
413
|
+
->(_) {
|
373
414
|
finalize_cli_argument_processing(options)
|
374
415
|
@fout.fout options.sort_by_key.to_yaml
|
375
416
|
}
|
376
417
|
when 'val_as_bool'
|
377
|
-
|
418
|
+
->(value) {
|
378
419
|
value.instance_of?(::String) ? (value.chomp != '0') : value
|
379
420
|
}
|
380
421
|
when 'val_as_int'
|
@@ -391,6 +432,8 @@ module MarkdownExec
|
|
391
432
|
end
|
392
433
|
end
|
393
434
|
|
435
|
+
def list_blocks; end
|
436
|
+
|
394
437
|
def list_default_env
|
395
438
|
menu_iter do |item|
|
396
439
|
next unless item[:env_var].present?
|
@@ -452,17 +495,6 @@ module MarkdownExec
|
|
452
495
|
data.map(&block)
|
453
496
|
end
|
454
497
|
|
455
|
-
def opts_list_files(options)
|
456
|
-
list_files_specified(
|
457
|
-
determine_filename(
|
458
|
-
specified_filename: options[:filename]&.present? ? options[:filename] : nil,
|
459
|
-
specified_folder: options[:path],
|
460
|
-
default_filename: 'README.md',
|
461
|
-
default_folder: '.'
|
462
|
-
)
|
463
|
-
)
|
464
|
-
end
|
465
|
-
|
466
498
|
def menu_export(data = menu_for_optparse)
|
467
499
|
data.map do |item|
|
468
500
|
item.delete(:procname)
|
@@ -484,9 +516,7 @@ module MarkdownExec
|
|
484
516
|
|
485
517
|
# - description and default
|
486
518
|
[item[:description],
|
487
|
-
(if item[:default].present?
|
488
|
-
"[#{value_for_cli item[:default]}]"
|
489
|
-
end)].compact.join(' '),
|
519
|
+
("[#{value_for_cli item[:default]}]" if item[:default].present?)].compact.join(' '),
|
490
520
|
|
491
521
|
# apply proccode, if present, to value
|
492
522
|
# save value to options hash if option is named
|
@@ -499,9 +529,15 @@ module MarkdownExec
|
|
499
529
|
].compact)
|
500
530
|
end
|
501
531
|
|
502
|
-
# Prepares and fetches file listings
|
503
532
|
def opts_prepare_file_list(options)
|
504
|
-
|
533
|
+
list_files_specified(
|
534
|
+
determine_filename(
|
535
|
+
specified_filename: options[:filename]&.present? ? options[:filename] : nil,
|
536
|
+
specified_folder: options[:path],
|
537
|
+
default_filename: 'README.md',
|
538
|
+
default_folder: '.'
|
539
|
+
)
|
540
|
+
)
|
505
541
|
end
|
506
542
|
|
507
543
|
# :reek:UtilityFunction ### temp
|
@@ -516,7 +552,8 @@ module MarkdownExec
|
|
516
552
|
|
517
553
|
def run
|
518
554
|
clear_required_file
|
519
|
-
|
555
|
+
initialize_and_parse_cli_options
|
556
|
+
execute_block_with_error_handling
|
520
557
|
@options.delete_required_temp_file
|
521
558
|
rescue StandardError
|
522
559
|
error_handler('run')
|