markdown_exec 1.8.4 → 1.8.6
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/.pryrc +1 -0
- data/CHANGELOG.md +18 -0
- data/Gemfile +2 -3
- data/Gemfile.lock +17 -6
- data/bin/bmde +1 -103
- data/bin/tab_completion.sh +15 -3
- data/examples/linked.md +52 -0
- data/examples/linked1.md +11 -1
- data/examples/linked2.md +5 -1
- data/examples/opts.md +23 -3
- data/lib/ansi_formatter.rb +0 -41
- data/lib/cached_nested_file_reader.rb +1 -7
- data/lib/constants.rb +17 -0
- data/lib/directory_searcher.rb +41 -5
- data/lib/filter.rb +2 -21
- data/lib/hash_delegator.rb +300 -177
- data/lib/link_history.rb +5 -2
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +20 -9
- data/lib/menu.src.yml +39 -12
- data/lib/menu.yml +37 -13
- data/lib/regexp_replacer.rb +58 -0
- metadata +4 -2
data/lib/hash_delegator.rb
CHANGED
@@ -26,6 +26,7 @@ require_relative 'fout'
|
|
26
26
|
require_relative 'hash'
|
27
27
|
require_relative 'link_history'
|
28
28
|
require_relative 'mdoc'
|
29
|
+
require_relative 'regexp'
|
29
30
|
require_relative 'string_util'
|
30
31
|
|
31
32
|
class String
|
@@ -296,17 +297,18 @@ module MarkdownExec
|
|
296
297
|
label_format_below: @delegate_object[:shell_code_label_format_below],
|
297
298
|
block_source: block_source
|
298
299
|
)
|
300
|
+
dependencies = (link_state&.inherited_dependencies || {}).merge(required[:dependencies] || {})
|
299
301
|
required[:unmet_dependencies] =
|
300
302
|
(required[:unmet_dependencies] || []) - (link_state&.inherited_block_names || [])
|
301
303
|
if required[:unmet_dependencies].present?
|
302
304
|
### filter against link_state.inherited_block_names
|
303
305
|
|
304
|
-
warn format_and_highlight_dependencies(
|
306
|
+
warn format_and_highlight_dependencies(dependencies,
|
305
307
|
highlight: required[:unmet_dependencies])
|
306
308
|
runtime_exception(:runtime_exception_error_level,
|
307
309
|
'unmet_dependencies, flag: runtime_exception_error_level', required[:unmet_dependencies])
|
308
310
|
elsif true
|
309
|
-
warn format_and_highlight_dependencies(
|
311
|
+
warn format_and_highlight_dependencies(dependencies,
|
310
312
|
highlight: [@delegate_object[:block_name]])
|
311
313
|
end
|
312
314
|
|
@@ -357,7 +359,7 @@ module MarkdownExec
|
|
357
359
|
@fout.fout "Error ENOENT: #{err.inspect}"
|
358
360
|
end
|
359
361
|
|
360
|
-
def
|
362
|
+
def load_cli_or_user_selected_block(all_blocks, menu_blocks, default)
|
361
363
|
if @delegate_object[:block_name].present?
|
362
364
|
block = all_blocks.find do |item|
|
363
365
|
item[:oname] == @delegate_object[:block_name]
|
@@ -371,7 +373,7 @@ module MarkdownExec
|
|
371
373
|
|
372
374
|
SelectedBlockMenuState.new(block, state)
|
373
375
|
rescue StandardError
|
374
|
-
error_handler('
|
376
|
+
error_handler('load_cli_or_user_selected_block')
|
375
377
|
end
|
376
378
|
|
377
379
|
# This method is responsible for handling the execution of generic blocks in a markdown document.
|
@@ -381,13 +383,13 @@ module MarkdownExec
|
|
381
383
|
# @param mdoc [Object] The markdown document object containing code blocks.
|
382
384
|
# @param selected [Hash] The selected item from the menu to be executed.
|
383
385
|
# @return [LoadFileLinkState] An object indicating whether to load the next block or reuse the current one.
|
384
|
-
def
|
385
|
-
link_state = nil, block_source:)
|
386
|
+
def compile_execute_and_trigger_reuse(mdoc, selected, link_state = nil, block_source:)
|
386
387
|
required_lines = collect_required_code_lines(mdoc, selected, link_state,
|
387
388
|
block_source: block_source)
|
388
389
|
output_or_approval = @delegate_object[:output_script] || @delegate_object[:user_must_approve]
|
389
390
|
display_required_code(required_lines) if output_or_approval
|
390
391
|
allow_execution = @delegate_object[:user_must_approve] ? prompt_for_user_approval(required_lines) : true
|
392
|
+
|
391
393
|
execute_required_lines(required_lines) if allow_execution
|
392
394
|
|
393
395
|
link_state.block_name = nil
|
@@ -599,8 +601,8 @@ module MarkdownExec
|
|
599
601
|
# @param opts [Hash] Options hash containing configuration settings.
|
600
602
|
# @param mdoc [YourMDocClass] An instance of the MDoc class.
|
601
603
|
#
|
602
|
-
def
|
603
|
-
|
604
|
+
def execute_shell_type(selected, mdoc, link_state = LinkState.new,
|
605
|
+
block_source:)
|
604
606
|
if selected.fetch(:shell, '') == BlockType::LINK
|
605
607
|
push_link_history_and_trigger_load(selected.fetch(:body, ''), mdoc, selected,
|
606
608
|
link_state)
|
@@ -609,11 +611,14 @@ module MarkdownExec
|
|
609
611
|
pop_link_history_and_trigger_load
|
610
612
|
|
611
613
|
elsif selected[:shell] == BlockType::OPTS
|
612
|
-
|
614
|
+
options_state = read_show_options_and_trigger_reuse(selected, link_state)
|
615
|
+
@menu_base_options.merge!(options_state.options)
|
616
|
+
@delegate_object.merge!(options_state.options)
|
617
|
+
options_state.load_file_link_state
|
613
618
|
|
614
619
|
else
|
615
|
-
|
616
|
-
|
620
|
+
compile_execute_and_trigger_reuse(mdoc, selected, link_state,
|
621
|
+
block_source: block_source)
|
617
622
|
end
|
618
623
|
end
|
619
624
|
|
@@ -805,7 +810,7 @@ module MarkdownExec
|
|
805
810
|
|
806
811
|
def link_history_push_and_next(
|
807
812
|
curr_block_name:, curr_document_filename:,
|
808
|
-
inherited_block_names:, inherited_lines:,
|
813
|
+
inherited_block_names:, inherited_dependencies:, inherited_lines:,
|
809
814
|
next_block_name:, next_document_filename:,
|
810
815
|
next_load_file:
|
811
816
|
)
|
@@ -814,6 +819,7 @@ module MarkdownExec
|
|
814
819
|
block_name: curr_block_name,
|
815
820
|
document_filename: curr_document_filename,
|
816
821
|
inherited_block_names: inherited_block_names,
|
822
|
+
inherited_dependencies: inherited_dependencies,
|
817
823
|
inherited_lines: inherited_lines
|
818
824
|
)
|
819
825
|
)
|
@@ -823,6 +829,7 @@ module MarkdownExec
|
|
823
829
|
block_name: next_block_name,
|
824
830
|
document_filename: next_document_filename,
|
825
831
|
inherited_block_names: inherited_block_names,
|
832
|
+
inherited_dependencies: inherited_dependencies,
|
826
833
|
inherited_lines: inherited_lines
|
827
834
|
)
|
828
835
|
)
|
@@ -841,7 +848,10 @@ module MarkdownExec
|
|
841
848
|
block = block_find(all_blocks, :oname, block_name)
|
842
849
|
return unless block
|
843
850
|
|
844
|
-
|
851
|
+
options_state = read_show_options_and_trigger_reuse(block)
|
852
|
+
@menu_base_options.merge!(options_state.options)
|
853
|
+
@delegate_object.merge!(options_state.options)
|
854
|
+
|
845
855
|
@most_recent_loaded_filename = @delegate_object[:filename]
|
846
856
|
true
|
847
857
|
end
|
@@ -911,10 +921,12 @@ module MarkdownExec
|
|
911
921
|
end
|
912
922
|
end
|
913
923
|
|
914
|
-
def
|
915
|
-
return false unless @
|
924
|
+
def shift_cli_argument!
|
925
|
+
return false unless @menu_base_options[:input_cli_rest].present?
|
916
926
|
|
917
|
-
@cli_block_name = @
|
927
|
+
@cli_block_name = @menu_base_options[:input_cli_rest].shift
|
928
|
+
# @delegate_object[:input_cli_rest].shift
|
929
|
+
# p [__LINE__, @cli_block_name, @menu_base_options[:input_cli_rest]]
|
918
930
|
true
|
919
931
|
end
|
920
932
|
|
@@ -978,6 +990,25 @@ module MarkdownExec
|
|
978
990
|
body.any? ? YAML.load(body.join("\n")) : {}
|
979
991
|
end
|
980
992
|
|
993
|
+
def pop_add_current_code_to_head_and_trigger_load(_link_state, block_names, code_lines,
|
994
|
+
dependencies)
|
995
|
+
pop = @link_history.pop # updatable
|
996
|
+
next_link_state = LinkState.new(
|
997
|
+
block_name: pop.block_name,
|
998
|
+
document_filename: pop.document_filename,
|
999
|
+
inherited_block_names:
|
1000
|
+
(pop.inherited_block_names + block_names).sort.uniq,
|
1001
|
+
inherited_dependencies:
|
1002
|
+
dependencies.merge(pop.inherited_dependencies || {}), ### merge, not replace, key data
|
1003
|
+
inherited_lines:
|
1004
|
+
code_merge(pop.inherited_lines, code_lines)
|
1005
|
+
)
|
1006
|
+
@link_history.push(next_link_state)
|
1007
|
+
|
1008
|
+
next_link_state.block_name = nil
|
1009
|
+
LoadFileLinkState.new(LoadFile::Load, next_link_state)
|
1010
|
+
end
|
1011
|
+
|
981
1012
|
# This method handles the back-link operation in the Markdown execution context.
|
982
1013
|
# It updates the history state and prepares to load the next block.
|
983
1014
|
#
|
@@ -986,10 +1017,11 @@ module MarkdownExec
|
|
986
1017
|
pop = @link_history.pop
|
987
1018
|
peek = @link_history.peek
|
988
1019
|
LoadFileLinkState.new(LoadFile::Load, LinkState.new(
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
1020
|
+
document_filename: pop.document_filename,
|
1021
|
+
inherited_block_names: peek.inherited_block_names,
|
1022
|
+
inherited_dependencies: peek.inherited_dependencies,
|
1023
|
+
inherited_lines: peek.inherited_lines
|
1024
|
+
))
|
993
1025
|
end
|
994
1026
|
|
995
1027
|
def post_execution_process
|
@@ -1135,21 +1167,52 @@ module MarkdownExec
|
|
1135
1167
|
)
|
1136
1168
|
code_lines = code_info[:code]
|
1137
1169
|
block_names = code_info[:block_names]
|
1170
|
+
dependencies = code_info[:dependencies]
|
1138
1171
|
else
|
1139
1172
|
block_names = []
|
1140
1173
|
code_lines = []
|
1174
|
+
dependencies = {}
|
1141
1175
|
end
|
1142
|
-
|
1143
1176
|
next_document_filename = link_block_data['file'] || @delegate_object[:filename]
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1177
|
+
|
1178
|
+
# if an eval link block, evaluate code_lines and return its standard output
|
1179
|
+
#
|
1180
|
+
if link_block_data.fetch('eval', false)
|
1181
|
+
all_code = code_merge(link_state&.inherited_lines, code_lines)
|
1182
|
+
output = `#{all_code.join("\n")}`.split("\n")
|
1183
|
+
label_format_above = @delegate_object[:shell_code_label_format_above]
|
1184
|
+
label_format_below = @delegate_object[:shell_code_label_format_below]
|
1185
|
+
block_source = { document_filename: link_state&.document_filename }
|
1186
|
+
|
1187
|
+
code_lines = [label_format_above && format(label_format_above,
|
1188
|
+
block_source.merge({ block_name: selected[:oname] }))] +
|
1189
|
+
output.map do |line|
|
1190
|
+
re = Regexp.new(link_block_data.fetch('pattern', '(?<line>.*)'))
|
1191
|
+
if re =~ line
|
1192
|
+
re.gsub_format(line, link_block_data.fetch('format', '%{line}'))
|
1193
|
+
end
|
1194
|
+
end.compact +
|
1195
|
+
[label_format_below && format(label_format_below,
|
1196
|
+
block_source.merge({ block_name: selected[:oname] }))]
|
1197
|
+
|
1198
|
+
end
|
1199
|
+
|
1200
|
+
if link_block_data['return']
|
1201
|
+
pop_add_current_code_to_head_and_trigger_load(link_state, block_names, code_lines,
|
1202
|
+
dependencies)
|
1203
|
+
|
1204
|
+
else
|
1205
|
+
link_history_push_and_next(
|
1206
|
+
curr_block_name: selected[:oname],
|
1207
|
+
curr_document_filename: @delegate_object[:filename],
|
1208
|
+
inherited_block_names: ((link_state&.inherited_block_names || []) + block_names).sort.uniq,
|
1209
|
+
inherited_dependencies: (link_state&.inherited_dependencies || {}).merge(dependencies || {}), ### merge, not replace, key data
|
1210
|
+
inherited_lines: code_merge(link_state&.inherited_lines, code_lines),
|
1211
|
+
next_block_name: link_block_data['block'] || '',
|
1212
|
+
next_document_filename: next_document_filename,
|
1213
|
+
next_load_file: next_document_filename == @delegate_object[:filename] ? LoadFile::Reuse : LoadFile::Load
|
1214
|
+
)
|
1215
|
+
end
|
1153
1216
|
end
|
1154
1217
|
|
1155
1218
|
# Reads required code blocks from a temporary file specified by an environment variable.
|
@@ -1210,86 +1273,208 @@ module MarkdownExec
|
|
1210
1273
|
# Markdown document, obtain approval, and execute the chosen block of code.
|
1211
1274
|
#
|
1212
1275
|
# @return [Nil] Returns nil if no code block is selected or an error occurs.
|
1213
|
-
def
|
1276
|
+
def document_menu_loop
|
1214
1277
|
@menu_base_options = @delegate_object
|
1278
|
+
link_state, block_name_from_cli, now_using_cli = initialize_selection_states
|
1279
|
+
menu_default_dname = nil
|
1280
|
+
|
1281
|
+
loop do
|
1282
|
+
# @bsp 'loop',block_name_from_cli,@cli_block_name
|
1283
|
+
block_name_from_cli, now_using_cli, blocks_in_file, menu_blocks, mdoc = \
|
1284
|
+
set_delobj_menu_loop_vars(block_name_from_cli, now_using_cli, link_state)
|
1285
|
+
|
1286
|
+
# cli or user selection
|
1287
|
+
#
|
1288
|
+
block_state = load_cli_or_user_selected_block(blocks_in_file, menu_blocks,
|
1289
|
+
menu_default_dname)
|
1290
|
+
if block_state.state == MenuState::EXIT
|
1291
|
+
# @bsp 'MenuState::EXIT -> break'
|
1292
|
+
break
|
1293
|
+
end
|
1294
|
+
|
1295
|
+
dump_and_warn_block_state(block_state.block)
|
1296
|
+
link_state, menu_default_dname = exec_bash_next_state(block_state.block, mdoc,
|
1297
|
+
link_state)
|
1298
|
+
if prompt_user_exit(block_name_from_cli, block_state.block)
|
1299
|
+
# @bsp 'prompt_user_exit -> break'
|
1300
|
+
break
|
1301
|
+
end
|
1302
|
+
|
1303
|
+
link_state.block_name, block_name_from_cli, cli_break = \
|
1304
|
+
next_state_from_cli(now_using_cli, block_state)
|
1305
|
+
|
1306
|
+
if cli_break
|
1307
|
+
# @bsp 'read_block_name_from_cli + next_link_state -> break'
|
1308
|
+
break
|
1309
|
+
end
|
1310
|
+
end
|
1311
|
+
rescue StandardError
|
1312
|
+
error_handler('document_menu_loop',
|
1313
|
+
{ abort: true })
|
1314
|
+
end
|
1315
|
+
|
1316
|
+
def next_state_from_cli(now_using_cli, block_state)
|
1317
|
+
was_using_cli = now_using_cli
|
1318
|
+
block_name_from_cli, = read_block_name_from_cli(now_using_cli)
|
1319
|
+
block_name, block_name_from_cli, cli_break = \
|
1320
|
+
next_link_state(block_name_from_cli, was_using_cli, block_state)
|
1321
|
+
|
1322
|
+
[block_name, block_name_from_cli, cli_break]
|
1323
|
+
end
|
1324
|
+
|
1325
|
+
def exec_bash_next_state(block_state_block, mdoc, link_state)
|
1326
|
+
lfls = execute_shell_type(
|
1327
|
+
block_state_block,
|
1328
|
+
mdoc,
|
1329
|
+
link_state,
|
1330
|
+
block_source: { document_filename: @delegate_object[:filename] }
|
1331
|
+
)
|
1332
|
+
|
1333
|
+
# if the same menu is being displayed, collect the display name of the selected menu item for use as the default item
|
1334
|
+
[lfls.link_state,
|
1335
|
+
lfls.load_file == LoadFile::Load ? nil : block_state_block[:dname]]
|
1336
|
+
end
|
1337
|
+
|
1338
|
+
def set_delobj_menu_loop_vars(block_name_from_cli, now_using_cli, link_state)
|
1339
|
+
block_name_from_cli, now_using_cli = \
|
1340
|
+
manage_cli_selection_state(block_name_from_cli, now_using_cli, link_state)
|
1341
|
+
set_delob_filename_block_name(link_state, block_name_from_cli)
|
1342
|
+
|
1343
|
+
# update @delegate_object and @menu_base_options in auto_load
|
1344
|
+
#
|
1345
|
+
blocks_in_file, menu_blocks, mdoc = mdoc_menu_and_blocks_from_nested_files
|
1346
|
+
dump_delobj(blocks_in_file, menu_blocks, link_state)
|
1347
|
+
|
1348
|
+
[block_name_from_cli, now_using_cli, blocks_in_file, menu_blocks, mdoc]
|
1349
|
+
end
|
1350
|
+
|
1351
|
+
# user prompt to exit if the menu will be displayed again
|
1352
|
+
#
|
1353
|
+
def prompt_user_exit(block_name_from_cli, block_state_block)
|
1354
|
+
!block_name_from_cli &&
|
1355
|
+
block_state_block[:shell] == BlockType::BASH &&
|
1356
|
+
@delegate_object[:pause_after_script_execution] &&
|
1357
|
+
prompt_select_continue == MenuState::EXIT
|
1358
|
+
end
|
1359
|
+
|
1360
|
+
def manage_cli_selection_state(block_name_from_cli, now_using_cli, link_state)
|
1361
|
+
if block_name_from_cli && @cli_block_name == '.'
|
1362
|
+
# @bsp 'pause cli control, allow user to select block'
|
1363
|
+
block_name_from_cli = false
|
1364
|
+
now_using_cli = false
|
1365
|
+
@menu_base_options[:block_name] = \
|
1366
|
+
@delegate_object[:block_name] = \
|
1367
|
+
link_state.block_name = \
|
1368
|
+
@cli_block_name = nil
|
1369
|
+
end
|
1370
|
+
|
1371
|
+
@delegate_object = @menu_base_options.dup
|
1372
|
+
@menu_user_clicked_back_link = false
|
1373
|
+
[block_name_from_cli, now_using_cli]
|
1374
|
+
end
|
1375
|
+
|
1376
|
+
def next_link_state(block_name_from_cli, was_using_cli, block_state)
|
1377
|
+
# @bsp 'next_link_state',block_name_from_cli, was_using_cli, block_state
|
1378
|
+
# Set block_name based on block_name_from_cli
|
1379
|
+
block_name = block_name_from_cli ? @cli_block_name : nil
|
1380
|
+
|
1381
|
+
# Determine the state of breaker based on was_using_cli and the block type
|
1382
|
+
breaker = !block_name_from_cli && was_using_cli && block_state.block[:shell] == BlockType::BASH
|
1383
|
+
|
1384
|
+
# Reset block_name_from_cli if the conditions are not met
|
1385
|
+
block_name_from_cli ||= false
|
1386
|
+
|
1387
|
+
[block_name, block_name_from_cli, breaker]
|
1388
|
+
end
|
1389
|
+
|
1390
|
+
# Initialize the selection states for the execution loop.
|
1391
|
+
def initialize_selection_states
|
1215
1392
|
link_state = LinkState.new(
|
1216
1393
|
block_name: @delegate_object[:block_name],
|
1217
1394
|
document_filename: @delegate_object[:filename]
|
1218
1395
|
)
|
1396
|
+
block_name_from_cli, now_using_cli = handle_cli_block_name(link_state)
|
1397
|
+
[link_state, block_name_from_cli, now_using_cli]
|
1398
|
+
end
|
1399
|
+
|
1400
|
+
# Update the state related to CLI block name.
|
1401
|
+
#
|
1402
|
+
# This method updates the flags indicating whether a CLI block name is being used
|
1403
|
+
# and if it was being used previously.
|
1404
|
+
#
|
1405
|
+
# @param block_name_from_cli [Boolean] Indicates if the block name is from CLI.
|
1406
|
+
# @return [Array] Returns the updated state of block name from CLI and its usage.
|
1407
|
+
def read_block_name_from_cli(block_name_from_cli)
|
1408
|
+
# was_using_cli = block_name_from_cli
|
1409
|
+
block_name_from_cli = shift_cli_argument!
|
1410
|
+
now_using_cli = block_name_from_cli
|
1411
|
+
|
1412
|
+
[block_name_from_cli, now_using_cli]
|
1413
|
+
end
|
1414
|
+
|
1415
|
+
# Update the block name in the link state and delegate object.
|
1416
|
+
#
|
1417
|
+
# This method updates the block name based on whether it was specified
|
1418
|
+
# through the CLI or derived from the link state.
|
1419
|
+
#
|
1420
|
+
# @param link_state [LinkState] The current link state object.
|
1421
|
+
# @param block_name_from_cli [Boolean] Indicates if the block name is from CLI.
|
1422
|
+
def set_delob_filename_block_name(link_state, block_name_from_cli)
|
1423
|
+
@delegate_object[:filename] = link_state.document_filename
|
1424
|
+
link_state.block_name = @delegate_object[:block_name] =
|
1425
|
+
block_name_from_cli ? @cli_block_name : link_state.block_name
|
1426
|
+
end
|
1427
|
+
|
1428
|
+
# Handle CLI block name and determine the current CLI usage state.
|
1429
|
+
#
|
1430
|
+
# This method processes the CLI block name from the link state and sets
|
1431
|
+
# the initial state for CLI usage.
|
1432
|
+
#
|
1433
|
+
# @param link_state [LinkState] The current link state object.
|
1434
|
+
# @return [Array] Returns the state of block name from CLI and current usage of CLI.
|
1435
|
+
def handle_cli_block_name(link_state)
|
1219
1436
|
block_name_from_cli = link_state.block_name.present?
|
1220
1437
|
@cli_block_name = link_state.block_name
|
1221
|
-
|
1222
|
-
menu_default_dname = nil
|
1438
|
+
now_using_cli = block_name_from_cli
|
1223
1439
|
|
1224
|
-
|
1225
|
-
|
1226
|
-
@delegate_object = @menu_base_options.dup
|
1227
|
-
@menu_user_clicked_back_link = false
|
1228
|
-
@delegate_object[:filename] = link_state.document_filename
|
1229
|
-
link_state.block_name = @delegate_object[:block_name] =
|
1230
|
-
block_name_from_cli ? @cli_block_name : link_state.block_name
|
1231
|
-
|
1232
|
-
blocks_in_file, menu_blocks, mdoc = mdoc_menu_and_blocks_from_nested_files
|
1233
|
-
|
1234
|
-
if @delegate_object[:dump_blocks_in_file]
|
1235
|
-
warn format_and_highlight_dependencies(
|
1236
|
-
compact_and_index_hash(blocks_in_file),
|
1237
|
-
label: 'blocks_in_file'
|
1238
|
-
)
|
1239
|
-
end
|
1240
|
-
if @delegate_object[:dump_menu_blocks]
|
1241
|
-
warn format_and_highlight_dependencies(
|
1242
|
-
compact_and_index_hash(menu_blocks),
|
1243
|
-
label: 'menu_blocks'
|
1244
|
-
)
|
1245
|
-
end
|
1246
|
-
|
1247
|
-
block_state = command_or_user_selected_block(blocks_in_file,
|
1248
|
-
menu_blocks, menu_default_dname)
|
1249
|
-
return if block_state.state == MenuState::EXIT
|
1440
|
+
[block_name_from_cli, now_using_cli]
|
1441
|
+
end
|
1250
1442
|
|
1251
|
-
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1443
|
+
# Outputs warnings based on the delegate object's configuration
|
1444
|
+
#
|
1445
|
+
# @param delegate_object [Hash] The delegate object containing configuration flags.
|
1446
|
+
# @param blocks_in_file [Hash] Hash of blocks present in the file.
|
1447
|
+
# @param menu_blocks [Hash] Hash of menu blocks.
|
1448
|
+
# @param link_state [LinkState] Current state of the link.
|
1449
|
+
def dump_delobj(blocks_in_file, menu_blocks, link_state)
|
1450
|
+
if @delegate_object[:dump_delegate_object]
|
1451
|
+
warn format_and_highlight_hash(@delegate_object, label: '@delegate_object')
|
1452
|
+
end
|
1256
1453
|
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1454
|
+
if @delegate_object[:dump_blocks_in_file]
|
1455
|
+
warn format_and_highlight_dependencies(compact_and_index_hash(blocks_in_file),
|
1456
|
+
label: 'blocks_in_file')
|
1457
|
+
end
|
1260
1458
|
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
block_source: { document_filename: @delegate_object[:filename] }
|
1266
|
-
)
|
1267
|
-
load_file = load_file_link_state.load_file
|
1268
|
-
link_state = load_file_link_state.link_state
|
1269
|
-
# if the same menu is being displayed, collect the display name of the selected menu item for use as the default item
|
1270
|
-
menu_default_dname = load_file == LoadFile::Load ? nil : block_state.block[:dname]
|
1459
|
+
if @delegate_object[:dump_menu_blocks]
|
1460
|
+
warn format_and_highlight_dependencies(compact_and_index_hash(menu_blocks),
|
1461
|
+
label: 'menu_blocks')
|
1462
|
+
end
|
1271
1463
|
|
1272
|
-
|
1273
|
-
#
|
1274
|
-
if !block_name_from_cli &&
|
1275
|
-
block_state.block[:shell] == BlockType::BASH &&
|
1276
|
-
@delegate_object[:pause_after_script_execution] &&
|
1277
|
-
prompt_select_continue == MenuState::EXIT
|
1278
|
-
return
|
1279
|
-
end
|
1464
|
+
return unless @delegate_object[:dump_inherited_lines]
|
1280
1465
|
|
1281
|
-
|
1282
|
-
|
1283
|
-
break if block_state.state == MenuState::CONTINUE && load_file == LoadFile::Load
|
1284
|
-
break if block_name_from_cli
|
1285
|
-
end
|
1286
|
-
break if load_file == LoadFile::Reuse
|
1466
|
+
warn format_and_highlight_lines(link_state.inherited_lines, label: 'inherited_lines')
|
1467
|
+
end
|
1287
1468
|
|
1288
|
-
|
1469
|
+
def dump_and_warn_block_state(block_state_block)
|
1470
|
+
if block_state_block.nil?
|
1471
|
+
Exceptions.warn_format("Block not found -- name: #{@delegate_object[:block_name]}",
|
1472
|
+
{ abort: true })
|
1289
1473
|
end
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1474
|
+
|
1475
|
+
return unless @delegate_object[:dump_selected_block]
|
1476
|
+
|
1477
|
+
warn block_state_block.to_yaml.sub(/^(?:---\n)?/, "Block:\n")
|
1293
1478
|
end
|
1294
1479
|
|
1295
1480
|
# Presents a TTY prompt to select an option or exit, returns metadata including option and selected
|
@@ -1406,12 +1591,6 @@ module MarkdownExec
|
|
1406
1591
|
)
|
1407
1592
|
end
|
1408
1593
|
|
1409
|
-
def update_delegate_and_target(key, value, tgt2)
|
1410
|
-
sym_key = key.to_sym
|
1411
|
-
@delegate_object[sym_key] = value
|
1412
|
-
tgt2[sym_key] = value if tgt2
|
1413
|
-
end
|
1414
|
-
|
1415
1594
|
# Updates the hierarchy of document headings based on the given line.
|
1416
1595
|
# Utilizes regular expressions to identify heading levels.
|
1417
1596
|
# @param line [String] The line of text to check for headings.
|
@@ -1487,6 +1666,10 @@ module MarkdownExec
|
|
1487
1666
|
# add line if it is depth 0 or option allows it
|
1488
1667
|
#
|
1489
1668
|
yield_line_if_selected(line, selected_messages, &block)
|
1669
|
+
|
1670
|
+
else
|
1671
|
+
# @bsp 'line is not recognized for block state'
|
1672
|
+
|
1490
1673
|
end
|
1491
1674
|
end
|
1492
1675
|
|
@@ -1509,14 +1692,21 @@ module MarkdownExec
|
|
1509
1692
|
# @param selected [Hash] Selected item from the menu containing a YAML body.
|
1510
1693
|
# @param tgt2 [Hash, nil] An optional target hash to update with YAML data.
|
1511
1694
|
# @return [LoadFileLinkState] An instance indicating the next action for loading files.
|
1512
|
-
def
|
1695
|
+
def read_show_options_and_trigger_reuse(selected, link_state = LinkState.new)
|
1696
|
+
obj = {}
|
1513
1697
|
data = YAML.load(selected[:body].join("\n"))
|
1514
1698
|
(data || []).each do |key, value|
|
1515
|
-
|
1699
|
+
sym_key = key.to_sym
|
1700
|
+
obj[sym_key] = value
|
1701
|
+
|
1516
1702
|
print_formatted_option(key, value) if @delegate_object[:menu_opts_set_format].present?
|
1517
1703
|
end
|
1704
|
+
|
1518
1705
|
link_state.block_name = nil
|
1519
|
-
|
1706
|
+
OpenStruct.new(options: obj,
|
1707
|
+
load_file_link_state: LoadFileLinkState.new(
|
1708
|
+
LoadFile::Reuse, link_state
|
1709
|
+
))
|
1520
1710
|
end
|
1521
1711
|
|
1522
1712
|
def wait_for_stream_processing
|
@@ -1716,6 +1906,7 @@ if $PROGRAM_NAME == __FILE__
|
|
1716
1906
|
expected_result = LoadFileLinkState.new(LoadFile::Load,
|
1717
1907
|
LinkState.new(block_name: 'sample_block',
|
1718
1908
|
document_filename: 'sample_file',
|
1909
|
+
inherited_dependencies: {},
|
1719
1910
|
inherited_lines: []))
|
1720
1911
|
assert_equal expected_result,
|
1721
1912
|
@hd.push_link_history_and_trigger_load(body, nil, FCB.new(block_name: 'sample_block',
|
@@ -1904,7 +2095,7 @@ if $PROGRAM_NAME == __FILE__
|
|
1904
2095
|
@hd.instance_variable_set(:@delegate_object,
|
1905
2096
|
{ block_name: 'block1' })
|
1906
2097
|
|
1907
|
-
result = @hd.
|
2098
|
+
result = @hd.load_cli_or_user_selected_block(all_blocks, [], nil)
|
1908
2099
|
|
1909
2100
|
assert_equal all_blocks.first, result.block
|
1910
2101
|
assert_nil result.state
|
@@ -1915,7 +2106,7 @@ if $PROGRAM_NAME == __FILE__
|
|
1915
2106
|
:some_state)
|
1916
2107
|
@hd.stubs(:wait_for_user_selected_block).returns(block_state)
|
1917
2108
|
|
1918
|
-
result = @hd.
|
2109
|
+
result = @hd.load_cli_or_user_selected_block([], [], nil)
|
1919
2110
|
|
1920
2111
|
assert_equal block_state.block, result.block
|
1921
2112
|
assert_equal :some_state, result.state
|
@@ -2207,7 +2398,7 @@ if $PROGRAM_NAME == __FILE__
|
|
2207
2398
|
@selected_item = mock('FCB')
|
2208
2399
|
end
|
2209
2400
|
|
2210
|
-
def
|
2401
|
+
def test_compile_execute_and_trigger_reuse_without_user_approval
|
2211
2402
|
# Mock the delegate object configuration
|
2212
2403
|
@hd.instance_variable_set(:@delegate_object,
|
2213
2404
|
{ output_script: false,
|
@@ -2217,7 +2408,7 @@ if $PROGRAM_NAME == __FILE__
|
|
2217
2408
|
# Expectations and assertions go here
|
2218
2409
|
end
|
2219
2410
|
|
2220
|
-
def
|
2411
|
+
def test_compile_execute_and_trigger_reuse_with_user_approval
|
2221
2412
|
# Mock the delegate object configuration
|
2222
2413
|
@hd.instance_variable_set(:@delegate_object,
|
2223
2414
|
{ output_script: false,
|
@@ -2227,7 +2418,7 @@ if $PROGRAM_NAME == __FILE__
|
|
2227
2418
|
# Expectations and assertions go here
|
2228
2419
|
end
|
2229
2420
|
|
2230
|
-
def
|
2421
|
+
def test_compile_execute_and_trigger_reuse_with_output_script
|
2231
2422
|
# Mock the delegate object configuration
|
2232
2423
|
@hd.instance_variable_set(:@delegate_object,
|
2233
2424
|
{ output_script: true,
|
@@ -2238,40 +2429,6 @@ if $PROGRAM_NAME == __FILE__
|
|
2238
2429
|
end
|
2239
2430
|
end
|
2240
2431
|
|
2241
|
-
class TestHashDelegatorHandleOptsBlock < Minitest::Test
|
2242
|
-
def setup
|
2243
|
-
@hd = HashDelegator.new
|
2244
|
-
@hd.instance_variable_set(:@delegate_object,
|
2245
|
-
{ menu_opts_set_format: 'Option: %<key>s, Value: %<value>s',
|
2246
|
-
menu_opts_set_color: :blue })
|
2247
|
-
@hd.stubs(:string_send_color)
|
2248
|
-
@hd.stubs(:print)
|
2249
|
-
end
|
2250
|
-
|
2251
|
-
def test_update_options_and_trigger_reuse
|
2252
|
-
selected = { body: ['option1: value1'] }
|
2253
|
-
tgt2 = {}
|
2254
|
-
|
2255
|
-
result = @hd.update_options_and_trigger_reuse(selected, tgt2)
|
2256
|
-
|
2257
|
-
assert_instance_of LoadFileLinkState, result
|
2258
|
-
assert_equal 'value1',
|
2259
|
-
@hd.instance_variable_get(:@delegate_object)[:option1]
|
2260
|
-
assert_equal 'value1', tgt2[:option1]
|
2261
|
-
end
|
2262
|
-
|
2263
|
-
def test_update_options_and_trigger_reuse_without_format
|
2264
|
-
selected = { body: ['option2: value2'] }
|
2265
|
-
@hd.instance_variable_set(:@delegate_object, {})
|
2266
|
-
|
2267
|
-
result = @hd.update_options_and_trigger_reuse(selected)
|
2268
|
-
|
2269
|
-
assert_instance_of LoadFileLinkState, result
|
2270
|
-
assert_equal 'value2',
|
2271
|
-
@hd.instance_variable_get(:@delegate_object)[:option2]
|
2272
|
-
end
|
2273
|
-
end
|
2274
|
-
|
2275
2432
|
# require 'stringio'
|
2276
2433
|
|
2277
2434
|
class TestHashDelegatorHandleStream < Minitest::Test
|
@@ -2339,39 +2496,6 @@ if $PROGRAM_NAME == __FILE__
|
|
2339
2496
|
end
|
2340
2497
|
end
|
2341
2498
|
|
2342
|
-
class TestHashDelegatorLoadAutoBlocks < Minitest::Test
|
2343
|
-
def setup
|
2344
|
-
@hd = HashDelegator.new
|
2345
|
-
@hd.stubs(:block_find).returns({})
|
2346
|
-
@hd.stubs(:update_options_and_trigger_reuse)
|
2347
|
-
end
|
2348
|
-
|
2349
|
-
def test_load_auto_blocks_with_new_filename
|
2350
|
-
@hd.instance_variable_set(:@delegate_object, {
|
2351
|
-
document_load_opts_block_name: 'load_block',
|
2352
|
-
filename: 'new_file'
|
2353
|
-
})
|
2354
|
-
assert @hd.load_auto_blocks([])
|
2355
|
-
end
|
2356
|
-
|
2357
|
-
def test_load_auto_blocks_with_same_filename
|
2358
|
-
@hd.instance_variable_set(:@delegate_object, {
|
2359
|
-
document_load_opts_block_name: 'load_block',
|
2360
|
-
filename: 'new_file'
|
2361
|
-
})
|
2362
|
-
@hd.instance_variable_set(:@most_recent_loaded_filename, 'new_file')
|
2363
|
-
assert_nil @hd.load_auto_blocks([])
|
2364
|
-
end
|
2365
|
-
|
2366
|
-
def test_load_auto_blocks_without_block_name
|
2367
|
-
@hd.instance_variable_set(:@delegate_object, {
|
2368
|
-
document_load_opts_block_name: nil,
|
2369
|
-
filename: 'new_file'
|
2370
|
-
})
|
2371
|
-
assert_nil @hd.load_auto_blocks([])
|
2372
|
-
end
|
2373
|
-
end
|
2374
|
-
|
2375
2499
|
class TestHashDelegatorMenuChromeColoredOption < Minitest::Test
|
2376
2500
|
def setup
|
2377
2501
|
@hd = HashDelegator.new
|
@@ -2566,7 +2690,6 @@ if $PROGRAM_NAME == __FILE__
|
|
2566
2690
|
end
|
2567
2691
|
end
|
2568
2692
|
|
2569
|
-
####
|
2570
2693
|
class TestHashDelegatorYieldToBlock < Minitest::Test
|
2571
2694
|
def setup
|
2572
2695
|
@hd = HashDelegator.new
|