markdown_exec 1.8.4 → 1.8.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|