markdown_exec 3.5.2 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -1
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/bats/block-type-shell-context-eval.bats +48 -0
- data/bats/block-type-ux-echo.bats +1 -1
- data/bats/block-type-ux-force.bats +1 -1
- data/bats/block-type-ux-invalid.bats +1 -1
- data/bats/block-type-ux-require.bats +1 -1
- data/bats/document-shell.bats +2 -2
- data/bats/import.bats +1 -1
- data/bats/load-vars-state-demo.bats +4 -4
- data/bin/tab_completion.sh +3 -3
- data/docs/dev/bats-document-configuration.md +1 -1
- data/docs/dev/block-type-shell-context-eval.md +52 -0
- data/docs/dev/block-type-shell-require-ux.md +6 -2
- data/docs/dev/block-type-ux-echo.md +3 -3
- data/docs/dev/block-type-ux-force.md +1 -1
- data/docs/dev/block-type-ux-require-chained.md +1 -1
- data/docs/dev/block-type-ux-require.md +2 -2
- data/docs/dev/import-parameter-symbols.md +1 -1
- data/docs/dev/linked-file.md +1 -1
- data/docs/dev/load-vars-state-demo.md +1 -1
- data/docs/dev/requiring-blocks.md +1 -1
- data/docs/dev/specs.md +2 -2
- data/docs/shell-script-evaluation.md +78 -0
- data/examples/link-blocks-vars.md +2 -2
- data/examples/linked.md +1 -1
- data/examples/linked1.md +2 -9
- data/examples/opts-blocks.md +2 -2
- data/examples/port-blocks.md +1 -1
- data/examples/variable-expansion.md +1 -1
- data/lib/cached_nested_file_reader.rb +10 -7
- data/lib/hash_delegator.rb +325 -284
- data/lib/input_sequencer.rb +4 -3
- data/lib/link_history.rb +76 -28
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/mdoc.rb +93 -65
- data/lib/menu.src.yml +5 -5
- data/lib/menu.yml +5 -5
- data/lib/ww.rb +1 -1
- metadata +5 -2
data/lib/hash_delegator.rb
CHANGED
|
@@ -217,7 +217,7 @@ module HashDelegatorSelf
|
|
|
217
217
|
#
|
|
218
218
|
# @example Basic execution without export
|
|
219
219
|
# result, exportable, new_lines = execute_bash_script_lines(
|
|
220
|
-
#
|
|
220
|
+
# transient_code: ["echo 'Hello'", "echo 'World'"],
|
|
221
221
|
# export: nil,
|
|
222
222
|
# force: false
|
|
223
223
|
# )
|
|
@@ -226,14 +226,14 @@ module HashDelegatorSelf
|
|
|
226
226
|
# @example Execution with export
|
|
227
227
|
# export = OpenStruct.new(name: "MY_VAR", exportable: true)
|
|
228
228
|
# result, exportable, new_lines = execute_bash_script_lines(
|
|
229
|
-
#
|
|
229
|
+
# transient_code: ["echo 'Hello World'"],
|
|
230
230
|
# export: export,
|
|
231
231
|
# force: true
|
|
232
232
|
# )
|
|
233
233
|
# # => [CommandResult, true, [{name: "MY_VAR", force: true, text: "Hello World\n"}]]
|
|
234
234
|
#
|
|
235
235
|
def execute_bash_script_lines(
|
|
236
|
-
|
|
236
|
+
transient_code: [],
|
|
237
237
|
export: nil,
|
|
238
238
|
export_name:,
|
|
239
239
|
force: false,
|
|
@@ -243,7 +243,7 @@ module HashDelegatorSelf
|
|
|
243
243
|
archive_time_format: nil # @delegate_object[:archive_time_format]
|
|
244
244
|
)
|
|
245
245
|
Tempfile.create('script_exec') do |temp_file|
|
|
246
|
-
temp_file.write(join_code_lines(
|
|
246
|
+
temp_file.write(join_code_lines(transient_code))
|
|
247
247
|
temp_file.close # Close the file before chmod and execution
|
|
248
248
|
File.chmod(0o755, temp_file.path)
|
|
249
249
|
|
|
@@ -282,20 +282,20 @@ module HashDelegatorSelf
|
|
|
282
282
|
exit_status: tsc.exit_code,
|
|
283
283
|
exportable: exportable_success,
|
|
284
284
|
new_lines: new_lines,
|
|
285
|
-
script:
|
|
285
|
+
script: transient_code,
|
|
286
286
|
stdout: tsc.transformed_output,
|
|
287
287
|
transformed_shell_command: tsc
|
|
288
288
|
)
|
|
289
289
|
end
|
|
290
290
|
rescue StandardError
|
|
291
|
-
wwe $!, '
|
|
291
|
+
wwe $!, 'transient_code:', transient_code, 'export:', export
|
|
292
292
|
# warn "Error executing script: #{err.message}"
|
|
293
293
|
# return failure result
|
|
294
294
|
CommandResult.new(
|
|
295
295
|
exit_status: CommandResult::EXIT_STATUS_FAIL,
|
|
296
296
|
exportable: false,
|
|
297
297
|
new_lines: [],
|
|
298
|
-
script:
|
|
298
|
+
script: transient_code,
|
|
299
299
|
stdout: ''
|
|
300
300
|
)
|
|
301
301
|
end
|
|
@@ -781,7 +781,7 @@ module MarkdownExec
|
|
|
781
781
|
|
|
782
782
|
@process_mutex = Mutex.new
|
|
783
783
|
@process_cv = ConditionVariable.new
|
|
784
|
-
@dml_link_state = Struct.new(:document_filename, :
|
|
784
|
+
@dml_link_state = Struct.new(:document_filename, :context_code)
|
|
785
785
|
.new(@delegate_object[:filename], [])
|
|
786
786
|
@dml_menu_blocks = []
|
|
787
787
|
@fcb_store = [] # all fcbs created
|
|
@@ -850,7 +850,7 @@ module MarkdownExec
|
|
|
850
850
|
add_inherited_lines(
|
|
851
851
|
link_state: link_state,
|
|
852
852
|
menu_blocks: menu_blocks
|
|
853
|
-
) if @delegate_object[:
|
|
853
|
+
) if @delegate_object[:menu_with_context_code]
|
|
854
854
|
|
|
855
855
|
# back before exit
|
|
856
856
|
add_back_option(
|
|
@@ -969,10 +969,10 @@ module MarkdownExec
|
|
|
969
969
|
# @param menu_blocks [Array] The array of menu block elements.
|
|
970
970
|
# @param position [Symbol] The position to insert the divider (:initial or :final).
|
|
971
971
|
def append_inherited_lines(link_state:, menu_blocks:, position: top)
|
|
972
|
-
return unless link_state.
|
|
972
|
+
return unless link_state.context_code_present?
|
|
973
973
|
|
|
974
974
|
insert_at_top = @delegate_object[:menu_inherited_lines_at_top]
|
|
975
|
-
chrome_blocks = link_state.
|
|
975
|
+
chrome_blocks = link_state.context_code_map do |line|
|
|
976
976
|
formatted = format(@delegate_object[:menu_inherited_lines_format],
|
|
977
977
|
{ line: line })
|
|
978
978
|
persist_fcb(
|
|
@@ -1190,7 +1190,7 @@ module MarkdownExec
|
|
|
1190
1190
|
occurrence_expressions: nil
|
|
1191
1191
|
)
|
|
1192
1192
|
evaluate_shell_expressions(
|
|
1193
|
-
(link_state&.
|
|
1193
|
+
(link_state&.context_code_block || ''),
|
|
1194
1194
|
commands,
|
|
1195
1195
|
initial_code_required: initial_code_required,
|
|
1196
1196
|
occurrence_expressions: occurrence_expressions
|
|
@@ -1209,7 +1209,7 @@ module MarkdownExec
|
|
|
1209
1209
|
exts: '.out.txt',
|
|
1210
1210
|
saved_asset_format:
|
|
1211
1211
|
shell_escape_asset_format(
|
|
1212
|
-
|
|
1212
|
+
transient_code: @dml_link_state.context_code,
|
|
1213
1213
|
shell: ShellType::BASH
|
|
1214
1214
|
)
|
|
1215
1215
|
).generate_name
|
|
@@ -1264,8 +1264,8 @@ module MarkdownExec
|
|
|
1264
1264
|
end
|
|
1265
1265
|
|
|
1266
1266
|
# return code resulting from evaluating all automatic blocks in order
|
|
1267
|
-
def
|
|
1268
|
-
all_blocks, mdoc: nil, default_only: true,
|
|
1267
|
+
def inherited_lines_from_auto_blocks(
|
|
1268
|
+
all_blocks, mdoc: nil, default_only: true, context_code: []
|
|
1269
1269
|
)
|
|
1270
1270
|
shell_block_name = @delegate_object[:document_load_shell_block_name]
|
|
1271
1271
|
vars_block_name = @delegate_object[:document_load_vars_block_name]
|
|
@@ -1287,18 +1287,18 @@ module MarkdownExec
|
|
|
1287
1287
|
if read_shell
|
|
1288
1288
|
# collect code from shell block
|
|
1289
1289
|
code = if mdoc
|
|
1290
|
-
|
|
1290
|
+
required_code = mdoc.collect_recursively_required_code(
|
|
1291
1291
|
anyname: fcb.id,
|
|
1292
1292
|
label_format_above:
|
|
1293
1293
|
@delegate_object[:shell_code_label_format_above],
|
|
1294
1294
|
label_format_below:
|
|
1295
1295
|
@delegate_object[:shell_code_label_format_below],
|
|
1296
1296
|
block_source: block_source,
|
|
1297
|
-
|
|
1297
|
+
context_code: context_code
|
|
1298
1298
|
)
|
|
1299
|
-
block_inherit =
|
|
1299
|
+
block_inherit = required_code[:context_code]
|
|
1300
1300
|
|
|
1301
|
-
|
|
1301
|
+
required_code[:transient_code]
|
|
1302
1302
|
else
|
|
1303
1303
|
fcb.body
|
|
1304
1304
|
end
|
|
@@ -1339,48 +1339,11 @@ module MarkdownExec
|
|
|
1339
1339
|
all_inherit += block_inherit
|
|
1340
1340
|
end
|
|
1341
1341
|
|
|
1342
|
-
|
|
1342
|
+
all_code.tap { wwr _1 }
|
|
1343
1343
|
rescue StandardError
|
|
1344
1344
|
wwe $!, 'all_blocks.count:', all_blocks.count
|
|
1345
1345
|
end
|
|
1346
1346
|
|
|
1347
|
-
# return code resulting from evaluating all UX blocks in order
|
|
1348
|
-
def code_from_auto_ux_blocks(
|
|
1349
|
-
all_blocks,
|
|
1350
|
-
mdoc
|
|
1351
|
-
)
|
|
1352
|
-
# do not reload the most recent filename
|
|
1353
|
-
unless @ux_most_recent_filename != @delegate_object[:filename]
|
|
1354
|
-
return
|
|
1355
|
-
end
|
|
1356
|
-
|
|
1357
|
-
@ux_most_recent_filename = @delegate_object[:filename]
|
|
1358
|
-
|
|
1359
|
-
# select all UX blocks, rejecting non-primary split
|
|
1360
|
-
blocks = select_automatic_ux_blocks(
|
|
1361
|
-
all_blocks.reject(&:is_split_rest?)
|
|
1362
|
-
)
|
|
1363
|
-
return if blocks.empty?
|
|
1364
|
-
|
|
1365
|
-
# collect code from all ux blocks
|
|
1366
|
-
(blocks.each.with_object([]) do |block, merged_options|
|
|
1367
|
-
command_result_w_e_t_nl =
|
|
1368
|
-
code_from_ux_block_to_set_environment_variables(
|
|
1369
|
-
block,
|
|
1370
|
-
mdoc,
|
|
1371
|
-
force: @delegate_object[:ux_auto_load_force_default],
|
|
1372
|
-
only_default: true,
|
|
1373
|
-
silent: true
|
|
1374
|
-
)
|
|
1375
|
-
if command_result_w_e_t_nl.failure?
|
|
1376
|
-
# if a block fails, proceed with next block
|
|
1377
|
-
merged_options
|
|
1378
|
-
else
|
|
1379
|
-
merged_options.push(command_result_w_e_t_nl.new_lines)
|
|
1380
|
-
end
|
|
1381
|
-
end).to_a
|
|
1382
|
-
end
|
|
1383
|
-
|
|
1384
1347
|
# return code resulting from evaluating all automatic VARS blocks in order
|
|
1385
1348
|
def code_from_auto_vars_blocks(
|
|
1386
1349
|
all_blocks,
|
|
@@ -1415,91 +1378,97 @@ module MarkdownExec
|
|
|
1415
1378
|
# set ENV value for the variable and return code lines for the same
|
|
1416
1379
|
# for BlockType::UX
|
|
1417
1380
|
def code_from_ux_block_to_set_environment_variables(
|
|
1418
|
-
selected, mdoc,
|
|
1419
|
-
required:
|
|
1381
|
+
selected, mdoc, context_code: nil, force: true, only_default: false,
|
|
1382
|
+
required: OpenStruct.new(context_code: [], transient_code: []),
|
|
1383
|
+
silent:
|
|
1420
1384
|
)
|
|
1421
1385
|
wwt :fcb, 'selected:', selected
|
|
1422
|
-
wwt :
|
|
1386
|
+
wwt :context_code, context_code
|
|
1423
1387
|
ret_command_result = nil
|
|
1424
1388
|
exit_prompt = @delegate_object[:prompt_filespec_back]
|
|
1425
1389
|
|
|
1426
|
-
required
|
|
1390
|
+
wwt :required, required
|
|
1391
|
+
required_code = mdoc&.collect_recursively_required_code(
|
|
1427
1392
|
anyname: selected_id_name(selected),
|
|
1428
1393
|
label_format_above: @delegate_object[:shell_code_label_format_above],
|
|
1429
1394
|
label_format_below: @delegate_object[:shell_code_label_format_below],
|
|
1430
1395
|
block_source: block_source,
|
|
1431
|
-
|
|
1396
|
+
context_code: context_code
|
|
1432
1397
|
)
|
|
1433
|
-
wwt :
|
|
1398
|
+
wwt :required_code, required_code
|
|
1434
1399
|
# new_inherited_lines = []
|
|
1435
1400
|
|
|
1436
1401
|
# process each ux block in sequence, setting ENV and collecting lines
|
|
1437
1402
|
concatenated_code_from_required_blocks = []
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1403
|
+
if required_code # exclude for tests
|
|
1404
|
+
required_code[:blocks]&.each do |block|
|
|
1405
|
+
next if block.type != BlockType::UX
|
|
1406
|
+
|
|
1407
|
+
wwt :fcb, 'a required block', block
|
|
1408
|
+
|
|
1409
|
+
body1 = block.raw_body || block.body
|
|
1410
|
+
case data = safe_yaml_load(body1.join("\n"))
|
|
1411
|
+
when Hash
|
|
1412
|
+
export = parse_yaml_of_ux_block(
|
|
1413
|
+
data,
|
|
1414
|
+
prompt: @delegate_object[:prompt_ux_enter_a_value],
|
|
1415
|
+
validate: '^(?<name>[^ ].*)$'
|
|
1416
|
+
)
|
|
1417
|
+
block.export = export
|
|
1418
|
+
block.export_act = FCB.act_source(export)
|
|
1419
|
+
block.export_init = FCB.init_source(export)
|
|
1420
|
+
|
|
1421
|
+
# required_code are variable names that must be set before the UX block is executed.
|
|
1422
|
+
# if any precondition is not set, the sequence is aborted.
|
|
1423
|
+
required_variables = []
|
|
1424
|
+
export.required&.each do |precondition|
|
|
1425
|
+
required_variables.push "[[ -z $#{precondition} ]] && exit #{CommandResult::EXIT_STATUS_REQUIRED_EMPTY}"
|
|
1426
|
+
end
|
|
1427
|
+
wwt :required_variables, 'required_variables',
|
|
1428
|
+
required_variables
|
|
1429
|
+
|
|
1430
|
+
eval_code = join_array_of_arrays(
|
|
1431
|
+
required[:context_code],
|
|
1432
|
+
context_code, # inherited code
|
|
1433
|
+
concatenated_code_from_required_blocks, # current block requirements
|
|
1434
|
+
required_variables, # test conditions
|
|
1435
|
+
required[:transient_code],
|
|
1436
|
+
required_code[:transient_code] # required by selected
|
|
1437
|
+
)
|
|
1438
|
+
wwt :eval_code, 'eval_code:', eval_code
|
|
1439
|
+
if only_default
|
|
1440
|
+
command_result_w_e_t_nl =
|
|
1441
|
+
ux_block_export_automatic(eval_code, export)
|
|
1442
|
+
# do not display warnings on initializing call
|
|
1443
|
+
return command_result_w_e_t_nl if command_result_w_e_t_nl.failure?
|
|
1476
1444
|
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1445
|
+
else
|
|
1446
|
+
command_result_w_e_t_nl =
|
|
1447
|
+
ux_block_export_activated(eval_code, export, exit_prompt)
|
|
1448
|
+
if command_result_w_e_t_nl.failure?
|
|
1449
|
+
if command_result_w_e_t_nl.warning&.present? && !silent
|
|
1450
|
+
warn command_result_w_e_t_nl.warning
|
|
1451
|
+
end
|
|
1452
|
+
return command_result_w_e_t_nl
|
|
1483
1453
|
end
|
|
1484
|
-
return command_result_w_e_t_nl
|
|
1485
1454
|
end
|
|
1486
|
-
|
|
1487
|
-
return command_result_w_e_t_nl if command_result_w_e_t_nl.failure?
|
|
1455
|
+
return command_result_w_e_t_nl if command_result_w_e_t_nl.failure?
|
|
1488
1456
|
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1457
|
+
# update the required lines for this and subsequent blocks
|
|
1458
|
+
command_result_w_e_t_nl.new_lines =
|
|
1459
|
+
process_command_result_lines(command_result_w_e_t_nl, export,
|
|
1460
|
+
concatenated_code_from_required_blocks)
|
|
1461
|
+
concatenated_code_from_required_blocks.concat(command_result_w_e_t_nl.new_lines)
|
|
1494
1462
|
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1463
|
+
concatenated_code_from_required_blocks = annotate_required_lines(
|
|
1464
|
+
'blk:UX', concatenated_code_from_required_blocks, block_name: selected.id
|
|
1465
|
+
)
|
|
1498
1466
|
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1467
|
+
command_result_w_e_t_nl.new_lines = concatenated_code_from_required_blocks
|
|
1468
|
+
ret_command_result = command_result_w_e_t_nl
|
|
1469
|
+
else
|
|
1470
|
+
raise "Invalid data type: #{data.inspect}"
|
|
1471
|
+
end
|
|
1503
1472
|
end
|
|
1504
1473
|
end
|
|
1505
1474
|
wwt :concatenated_code_from_required_blocks,
|
|
@@ -1513,19 +1482,19 @@ module MarkdownExec
|
|
|
1513
1482
|
wwt :cr, ret, caller.deref
|
|
1514
1483
|
end
|
|
1515
1484
|
rescue StandardError
|
|
1516
|
-
wwe $!, 'selected:', selected, '
|
|
1485
|
+
wwe $!, 'selected:', selected, 'required_code:', required_code, 'block:', block,
|
|
1517
1486
|
'data:', data
|
|
1518
1487
|
end
|
|
1519
1488
|
|
|
1520
1489
|
# def
|
|
1521
1490
|
# sets ENV
|
|
1522
1491
|
def code_from_vars_block_to_set_environment_variables(selected)
|
|
1523
|
-
|
|
1492
|
+
transient_code = []
|
|
1524
1493
|
case data = YAML.load(selected.body.join("\n"))
|
|
1525
1494
|
when Hash
|
|
1526
1495
|
data.each do |key, value|
|
|
1527
1496
|
EnvInterface.set(key, value.to_s)
|
|
1528
|
-
|
|
1497
|
+
transient_code << assign_key_value_in_bash(key, value)
|
|
1529
1498
|
|
|
1530
1499
|
next unless @delegate_object[:menu_vars_set_format].present?
|
|
1531
1500
|
|
|
@@ -1537,10 +1506,10 @@ module MarkdownExec
|
|
|
1537
1506
|
print string_send_color(formatted_string, :menu_vars_set_color)
|
|
1538
1507
|
end
|
|
1539
1508
|
end
|
|
1540
|
-
annotate_required_lines('blk:VARS',
|
|
1509
|
+
annotate_required_lines('blk:VARS', transient_code, block_name: selected.id)
|
|
1541
1510
|
rescue StandardError
|
|
1542
1511
|
wwe 'selected:', selected, 'data:', data, 'key:', key, 'value:', value,
|
|
1543
|
-
'
|
|
1512
|
+
'transient_code:', transient_code, 'formatted_string:', formatted_string
|
|
1544
1513
|
end
|
|
1545
1514
|
|
|
1546
1515
|
# make a single line of shell code to assign an escaped value to a variable
|
|
@@ -1597,7 +1566,8 @@ module MarkdownExec
|
|
|
1597
1566
|
else
|
|
1598
1567
|
@run_state.in_own_window = false
|
|
1599
1568
|
command_execute_in_process(
|
|
1600
|
-
args: args,
|
|
1569
|
+
args: args,
|
|
1570
|
+
command: command,
|
|
1601
1571
|
erls: erls,
|
|
1602
1572
|
filename: @delegate_object[:filename],
|
|
1603
1573
|
shell: shell
|
|
@@ -1679,8 +1649,7 @@ module MarkdownExec
|
|
|
1679
1649
|
# containing code blocks.
|
|
1680
1650
|
# @param selected [Hash] The selected item from the menu
|
|
1681
1651
|
# to be executed.
|
|
1682
|
-
# @return [
|
|
1683
|
-
# the next block or reuse the current one.
|
|
1652
|
+
# @return [Array] context_code
|
|
1684
1653
|
def compile_execute_and_trigger_reuse(
|
|
1685
1654
|
mdoc:, selected:, block_source:, link_state:
|
|
1686
1655
|
)
|
|
@@ -1697,18 +1666,18 @@ module MarkdownExec
|
|
|
1697
1666
|
end
|
|
1698
1667
|
end
|
|
1699
1668
|
|
|
1700
|
-
|
|
1669
|
+
required_code = execute_block_type_port_code_lines(
|
|
1701
1670
|
mdoc: mdoc, selected: selected,
|
|
1702
1671
|
link_state: link_state, block_source: block_source
|
|
1703
1672
|
)
|
|
1704
1673
|
output_or_approval = @delegate_object[:output_script] ||
|
|
1705
1674
|
@delegate_object[:user_must_approve]
|
|
1706
1675
|
if output_or_approval
|
|
1707
|
-
display_required_code(required_lines:
|
|
1676
|
+
display_required_code(required_lines: required_code[:transient_code])
|
|
1708
1677
|
end
|
|
1709
1678
|
allow_execution = if @delegate_object[:user_must_approve]
|
|
1710
1679
|
prompt_for_user_approval(
|
|
1711
|
-
required_lines:
|
|
1680
|
+
required_lines: required_code[:transient_code],
|
|
1712
1681
|
selected: selected
|
|
1713
1682
|
)
|
|
1714
1683
|
else
|
|
@@ -1716,16 +1685,28 @@ module MarkdownExec
|
|
|
1716
1685
|
end
|
|
1717
1686
|
|
|
1718
1687
|
if allow_execution
|
|
1688
|
+
script_lines = ( #HashDelegator.join_code_lines(
|
|
1689
|
+
# ['# prior context'] +
|
|
1690
|
+
(link_state&.context_code || []) +
|
|
1691
|
+
# ['# new context'] +
|
|
1692
|
+
required_code[:context_code] +
|
|
1693
|
+
# ['# new transient'] +
|
|
1694
|
+
required_code[:transient_code]
|
|
1695
|
+
)
|
|
1719
1696
|
execute_required_lines(
|
|
1720
1697
|
blockname: selected_id_name(selected),
|
|
1721
1698
|
erls: { play_bin: play_bin,
|
|
1722
1699
|
shell: selected_shell(selected.shell) },
|
|
1723
|
-
|
|
1700
|
+
script_lines: script_lines,
|
|
1724
1701
|
shell: selected_shell(selected.shell)
|
|
1725
1702
|
)
|
|
1726
1703
|
end
|
|
1727
1704
|
|
|
1728
1705
|
link_state.block_name = nil
|
|
1706
|
+
|
|
1707
|
+
required_code[:context_code]
|
|
1708
|
+
rescue StandardError
|
|
1709
|
+
wwe $!
|
|
1729
1710
|
end
|
|
1730
1711
|
|
|
1731
1712
|
# Check if the expression contains wildcard characters
|
|
@@ -2036,6 +2017,8 @@ module MarkdownExec
|
|
|
2036
2017
|
# filter block if selected in menu
|
|
2037
2018
|
return true if @run_state.source.block_name_from_cli
|
|
2038
2019
|
|
|
2020
|
+
return true if @delegate_object[:block_name].empty?
|
|
2021
|
+
|
|
2039
2022
|
# return false if @prior_execution_block == @delegate_object[:block_name]
|
|
2040
2023
|
if @prior_execution_block == @delegate_object[:block_name]
|
|
2041
2024
|
return @allowed_execution_block == @prior_execution_block ||
|
|
@@ -2212,10 +2195,10 @@ module MarkdownExec
|
|
|
2212
2195
|
warn format_and_highlight_lines(link_state.inherited_dependencies,
|
|
2213
2196
|
label: 'inherited_dependencies')
|
|
2214
2197
|
end
|
|
2215
|
-
return unless @delegate_object[:
|
|
2198
|
+
return unless @delegate_object[:dump_context_code]
|
|
2216
2199
|
|
|
2217
|
-
warn format_and_highlight_lines(link_state.
|
|
2218
|
-
label: '
|
|
2200
|
+
warn format_and_highlight_lines(link_state.context_code,
|
|
2201
|
+
label: 'context_code')
|
|
2219
2202
|
end
|
|
2220
2203
|
|
|
2221
2204
|
# Opens text in an editor for user modification and
|
|
@@ -2301,7 +2284,7 @@ module MarkdownExec
|
|
|
2301
2284
|
vux_edit_inherited
|
|
2302
2285
|
return :break if pause_user_exit
|
|
2303
2286
|
|
|
2304
|
-
next_state_append_code(selected, link_state, [])
|
|
2287
|
+
next_state_append_code(selected, link_state, context_code: [])
|
|
2305
2288
|
|
|
2306
2289
|
elsif selected.type == BlockType::HISTORY
|
|
2307
2290
|
debounce_reset
|
|
@@ -2314,23 +2297,25 @@ module MarkdownExec
|
|
|
2314
2297
|
|
|
2315
2298
|
elsif selected.type == BlockType::LINK
|
|
2316
2299
|
debounce_reset
|
|
2317
|
-
execute_block_type_link_with_state(
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2300
|
+
execute_block_type_link_with_state(
|
|
2301
|
+
link_block_body: selected.body,
|
|
2302
|
+
mdoc: mdoc,
|
|
2303
|
+
selected: selected,
|
|
2304
|
+
link_state: link_state,
|
|
2305
|
+
block_source: block_source
|
|
2306
|
+
)
|
|
2322
2307
|
|
|
2323
2308
|
elsif selected.type == BlockType::LOAD
|
|
2324
2309
|
debounce_reset
|
|
2325
2310
|
load_result = execute_block_type_load_code_lines(selected)
|
|
2326
|
-
next_state_append_code(selected, link_state, load_result.code,
|
|
2327
|
-
|
|
2311
|
+
next_state_append_code(selected, link_state, context_code: load_result.code,
|
|
2312
|
+
mode: load_result.mode)
|
|
2328
2313
|
|
|
2329
2314
|
elsif selected.type == BlockType::SAVE
|
|
2330
2315
|
debounce_reset
|
|
2331
2316
|
|
|
2332
2317
|
execute_block_type_save(
|
|
2333
|
-
|
|
2318
|
+
transient_code: link_state&.context_code,
|
|
2334
2319
|
selected: selected
|
|
2335
2320
|
)
|
|
2336
2321
|
|
|
@@ -2352,7 +2337,7 @@ module MarkdownExec
|
|
|
2352
2337
|
|
|
2353
2338
|
elsif selected.type == BlockType::OPTS
|
|
2354
2339
|
debounce_reset
|
|
2355
|
-
|
|
2340
|
+
transient_code = []
|
|
2356
2341
|
options_state = read_show_options_and_trigger_reuse(
|
|
2357
2342
|
link_state: link_state,
|
|
2358
2343
|
mdoc: @dml_mdoc,
|
|
@@ -2361,7 +2346,7 @@ module MarkdownExec
|
|
|
2361
2346
|
update_menu_base(options_state.options)
|
|
2362
2347
|
|
|
2363
2348
|
link_state = LinkState.new
|
|
2364
|
-
next_state_append_code(selected, link_state,
|
|
2349
|
+
next_state_append_code(selected, link_state, context_code: transient_code)
|
|
2365
2350
|
|
|
2366
2351
|
elsif selected.type == BlockType::PORT
|
|
2367
2352
|
debounce_reset
|
|
@@ -2370,22 +2355,22 @@ module MarkdownExec
|
|
|
2370
2355
|
selected: selected,
|
|
2371
2356
|
link_state: link_state,
|
|
2372
2357
|
block_source: block_source
|
|
2373
|
-
)
|
|
2374
|
-
next_state_append_code(selected, link_state, required_lines)
|
|
2358
|
+
)[:context_code]
|
|
2359
|
+
next_state_append_code(selected, link_state, context_code: required_lines)
|
|
2375
2360
|
|
|
2376
2361
|
elsif selected.type == BlockType::UX
|
|
2377
2362
|
debounce_reset
|
|
2378
2363
|
command_result_w_e_t_nl = code_from_ux_block_to_set_environment_variables(
|
|
2379
2364
|
selected,
|
|
2380
2365
|
@dml_mdoc,
|
|
2381
|
-
|
|
2366
|
+
context_code: @dml_link_state.context_code,
|
|
2382
2367
|
only_default: false,
|
|
2383
2368
|
silent: true
|
|
2384
2369
|
)
|
|
2385
2370
|
next_state_append_code(
|
|
2386
2371
|
selected,
|
|
2387
2372
|
link_state,
|
|
2388
|
-
command_result_w_e_t_nl.failure? ? [] : command_result_w_e_t_nl.new_lines
|
|
2373
|
+
context_code: command_result_w_e_t_nl.failure? ? [] : command_result_w_e_t_nl.new_lines
|
|
2389
2374
|
)
|
|
2390
2375
|
|
|
2391
2376
|
elsif selected.type == BlockType::VARS
|
|
@@ -2393,7 +2378,7 @@ module MarkdownExec
|
|
|
2393
2378
|
next_state_append_code(
|
|
2394
2379
|
selected,
|
|
2395
2380
|
link_state,
|
|
2396
|
-
code_from_vars_block_to_set_environment_variables(selected)
|
|
2381
|
+
context_code: code_from_vars_block_to_set_environment_variables(selected)
|
|
2397
2382
|
)
|
|
2398
2383
|
|
|
2399
2384
|
elsif COLLAPSIBLE_TYPES.include?(selected.type)
|
|
@@ -2403,11 +2388,13 @@ module MarkdownExec
|
|
|
2403
2388
|
|
|
2404
2389
|
elsif debounce_allows
|
|
2405
2390
|
# SHELL type
|
|
2406
|
-
compile_execute_and_trigger_reuse(
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2391
|
+
context_code = compile_execute_and_trigger_reuse(
|
|
2392
|
+
mdoc: mdoc,
|
|
2393
|
+
selected: selected,
|
|
2394
|
+
link_state: link_state,
|
|
2395
|
+
block_source: block_source
|
|
2396
|
+
)
|
|
2397
|
+
next_state_set_code(selected, link_state, context_code)
|
|
2411
2398
|
|
|
2412
2399
|
else
|
|
2413
2400
|
LoadFileLinkState.new(LoadFile::REUSE, link_state)
|
|
@@ -2501,30 +2488,31 @@ module MarkdownExec
|
|
|
2501
2488
|
## collect blocks specified by block
|
|
2502
2489
|
#
|
|
2503
2490
|
if mdoc
|
|
2504
|
-
|
|
2491
|
+
required_code = mdoc.collect_recursively_required_code(
|
|
2505
2492
|
anyname: selected_id_name(selected),
|
|
2506
2493
|
block_source: block_source,
|
|
2507
2494
|
label_format_above: @delegate_object[:shell_code_label_format_above],
|
|
2508
2495
|
label_format_below: @delegate_object[:shell_code_label_format_below],
|
|
2509
|
-
|
|
2496
|
+
context_code: link_state&.context_code || []
|
|
2510
2497
|
)
|
|
2511
|
-
|
|
2512
|
-
|
|
2498
|
+
|
|
2499
|
+
context_code = annotate_required_lines(
|
|
2500
|
+
'blk:LINK', required_code[:context_code], block_name: selected.id
|
|
2513
2501
|
)
|
|
2514
|
-
block_names =
|
|
2515
|
-
dependencies =
|
|
2502
|
+
block_names = required_code[:block_names]
|
|
2503
|
+
dependencies = required_code[:dependencies]
|
|
2516
2504
|
else
|
|
2517
2505
|
block_names = []
|
|
2518
|
-
|
|
2506
|
+
context_code = []
|
|
2519
2507
|
dependencies = {}
|
|
2520
2508
|
end
|
|
2521
2509
|
|
|
2522
2510
|
# load key and values from link block into current environment
|
|
2523
2511
|
#
|
|
2524
2512
|
if link_block_data[LinkKeys::VARS]
|
|
2525
|
-
|
|
2513
|
+
context_code << BashCommentFormatter.format_comment(selected.pub_name)
|
|
2526
2514
|
link_block_data[LinkKeys::VARS].each do |key, value|
|
|
2527
|
-
|
|
2515
|
+
context_code << assign_key_value_in_bash(key, value)
|
|
2528
2516
|
EnvInterface.set(key, value.to_s)
|
|
2529
2517
|
end
|
|
2530
2518
|
end
|
|
@@ -2535,20 +2523,20 @@ module MarkdownExec
|
|
|
2535
2523
|
load_filespec = load_filespec_from_expression(load_expr)
|
|
2536
2524
|
if load_filespec
|
|
2537
2525
|
begin
|
|
2538
|
-
|
|
2539
|
-
|
|
2526
|
+
context_code += File.readlines(load_filespec,
|
|
2527
|
+
chomp: true)
|
|
2540
2528
|
rescue Errno::ENOENT
|
|
2541
2529
|
report_error($ERROR_INFO)
|
|
2542
2530
|
end
|
|
2543
2531
|
end
|
|
2544
2532
|
end
|
|
2545
2533
|
|
|
2546
|
-
# if an eval link block, evaluate
|
|
2534
|
+
# if an eval link block, evaluate context_code and return its standard output
|
|
2547
2535
|
#
|
|
2548
2536
|
if link_block_data.fetch(LinkKeys::EVAL, false) ||
|
|
2549
2537
|
link_block_data.fetch(LinkKeys::EXEC, false)
|
|
2550
|
-
|
|
2551
|
-
link_state,
|
|
2538
|
+
context_code = link_block_data_eval(
|
|
2539
|
+
link_state, context_code, selected, link_block_data,
|
|
2552
2540
|
block_source: block_source,
|
|
2553
2541
|
shell: @delegate_object[:block_type_default]
|
|
2554
2542
|
)
|
|
@@ -2563,13 +2551,16 @@ module MarkdownExec
|
|
|
2563
2551
|
nil
|
|
2564
2552
|
) || link_block_data.fetch(LinkKeys::BLOCK, nil) || ''
|
|
2565
2553
|
|
|
2566
|
-
|
|
2567
|
-
'blk:LINK',
|
|
2554
|
+
context_code = annotate_required_lines(
|
|
2555
|
+
'blk:LINK', context_code, block_name: selected.id
|
|
2556
|
+
)
|
|
2557
|
+
context_code = annotate_required_lines(
|
|
2558
|
+
'blk:LINK', context_code, block_name: selected.id
|
|
2568
2559
|
)
|
|
2569
2560
|
|
|
2570
2561
|
if link_block_data[LinkKeys::RETURN]
|
|
2571
2562
|
pop_add_current_code_to_head_and_trigger_load(
|
|
2572
|
-
link_state, block_names,
|
|
2563
|
+
link_state, block_names, context_code,
|
|
2573
2564
|
dependencies, selected, next_block_name: next_block_name
|
|
2574
2565
|
)
|
|
2575
2566
|
|
|
@@ -2582,8 +2573,8 @@ module MarkdownExec
|
|
|
2582
2573
|
((link_state&.inherited_block_names || []) + block_names).sort.uniq,
|
|
2583
2574
|
inherited_dependencies:
|
|
2584
2575
|
(link_state&.inherited_dependencies || {}).merge(dependencies || {}), ### merge, not replace, key data
|
|
2585
|
-
|
|
2586
|
-
link_state&.
|
|
2576
|
+
context_code: HashDelegator.flatten_and_compact_arrays(
|
|
2577
|
+
link_state&.context_code, context_code
|
|
2587
2578
|
),
|
|
2588
2579
|
keep_code: link_state&.keep_code,
|
|
2589
2580
|
next_block_name: next_block_name,
|
|
@@ -2680,32 +2671,34 @@ module MarkdownExec
|
|
|
2680
2671
|
#
|
|
2681
2672
|
# @param mdoc [YourMDocClass] An instance of the MDoc class.
|
|
2682
2673
|
# @param selected [Hash] The selected block.
|
|
2683
|
-
# @return [
|
|
2674
|
+
# @return [OpenStruct] context and transient code
|
|
2684
2675
|
def execute_block_type_port_code_lines(mdoc:, selected:, block_source:,
|
|
2685
2676
|
link_state: LinkState.new)
|
|
2686
|
-
|
|
2677
|
+
required_code = mdoc.collect_recursively_required_code(
|
|
2687
2678
|
anyname: selected_id_name(selected),
|
|
2688
2679
|
label_format_above: @delegate_object[:shell_code_label_format_above],
|
|
2689
2680
|
label_format_below: @delegate_object[:shell_code_label_format_below],
|
|
2690
2681
|
block_source: block_source,
|
|
2691
|
-
|
|
2692
|
-
) # !!t '
|
|
2682
|
+
context_code: link_state&.context_code || []
|
|
2683
|
+
) # !!t 'required_code'
|
|
2693
2684
|
dependencies = (
|
|
2694
2685
|
link_state&.inherited_dependencies || {}
|
|
2695
|
-
).merge(
|
|
2696
|
-
|
|
2697
|
-
|
|
2686
|
+
).merge(required_code[:dependencies] || {})
|
|
2687
|
+
|
|
2688
|
+
required_code[:unmet_dependencies] = (
|
|
2689
|
+
required_code[:unmet_dependencies] || []
|
|
2698
2690
|
) - (link_state&.inherited_block_names || [])
|
|
2699
|
-
|
|
2691
|
+
|
|
2692
|
+
if required_code[:unmet_dependencies].present?
|
|
2700
2693
|
### filter against link_state.inherited_block_names
|
|
2701
2694
|
|
|
2702
2695
|
warn format_and_highlight_dependencies(
|
|
2703
|
-
dependencies, highlight:
|
|
2696
|
+
dependencies, highlight: required_code[:unmet_dependencies]
|
|
2704
2697
|
)
|
|
2705
2698
|
runtime_exception(
|
|
2706
2699
|
:runtime_exception_error_level,
|
|
2707
2700
|
'unmet_dependencies, flag: runtime_exception_error_level',
|
|
2708
|
-
|
|
2701
|
+
required_code[:unmet_dependencies]
|
|
2709
2702
|
)
|
|
2710
2703
|
elsif @delegate_object[:dump_dependencies]
|
|
2711
2704
|
warn format_and_highlight_dependencies(
|
|
@@ -2716,8 +2709,11 @@ module MarkdownExec
|
|
|
2716
2709
|
|
|
2717
2710
|
if selected[:type] == BlockType::OPTS
|
|
2718
2711
|
# body of blocks is returned as a list of lines to be read an YAML
|
|
2719
|
-
|
|
2720
|
-
|
|
2712
|
+
OpenStruct.new(
|
|
2713
|
+
context_code: HashDelegator.flatten_and_compact_arrays(
|
|
2714
|
+
required_code[:blocks].map(&:body).flatten(1)
|
|
2715
|
+
),
|
|
2716
|
+
transient_code: []
|
|
2721
2717
|
)
|
|
2722
2718
|
else
|
|
2723
2719
|
# code from the selected VARS block
|
|
@@ -2727,31 +2723,41 @@ module MarkdownExec
|
|
|
2727
2723
|
[]
|
|
2728
2724
|
end
|
|
2729
2725
|
|
|
2730
|
-
# activate UX blocks in the
|
|
2726
|
+
# activate UX blocks in the required_code list
|
|
2731
2727
|
command_result_w_e_t_nl = code_from_ux_block_to_set_environment_variables(
|
|
2732
2728
|
selected,
|
|
2733
2729
|
@dml_mdoc,
|
|
2734
|
-
|
|
2730
|
+
context_code: required_code[:context_code] + required_code[:transient_code],
|
|
2735
2731
|
only_default: false,
|
|
2736
|
-
required:
|
|
2732
|
+
required:
|
|
2733
|
+
OpenStruct.new(context_code: [], transient_code: vars_code),
|
|
2737
2734
|
silent: false
|
|
2738
2735
|
)
|
|
2739
2736
|
ux_code = command_result_w_e_t_nl.failure? ? [] : command_result_w_e_t_nl.new_lines
|
|
2740
2737
|
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2738
|
+
OpenStruct.new(
|
|
2739
|
+
context_code: HashDelegator.flatten_and_compact_arrays(
|
|
2740
|
+
link_state&.context_code,
|
|
2741
|
+
annotate_required_lines(
|
|
2742
|
+
'blk:PORT',
|
|
2743
|
+
(required_code[:context_code] || []) + vars_code + ux_code,
|
|
2744
|
+
block_name: selected.id
|
|
2745
|
+
)
|
|
2746
|
+
),
|
|
2747
|
+
transient_code: HashDelegator.flatten_and_compact_arrays(
|
|
2748
|
+
annotate_required_lines(
|
|
2749
|
+
'blk:PORT',
|
|
2750
|
+
required_code[:transient_code],
|
|
2751
|
+
block_name: selected.id
|
|
2752
|
+
)
|
|
2747
2753
|
)
|
|
2748
2754
|
)
|
|
2749
2755
|
end
|
|
2750
2756
|
rescue StandardError
|
|
2751
|
-
wwe(
|
|
2757
|
+
wwe(required_code, ux_code, { error: $!, callback: $@[0] })
|
|
2752
2758
|
end
|
|
2753
2759
|
|
|
2754
|
-
def execute_block_type_save(
|
|
2760
|
+
def execute_block_type_save(transient_code:, selected:)
|
|
2755
2761
|
block_data = HashDelegator.parse_yaml_data_from_body(selected.body)
|
|
2756
2762
|
directory_glob = if block_data['directory']
|
|
2757
2763
|
File.join(
|
|
@@ -2772,7 +2778,7 @@ module MarkdownExec
|
|
|
2772
2778
|
end
|
|
2773
2779
|
|
|
2774
2780
|
File.write(save_filespec,
|
|
2775
|
-
HashDelegator.join_code_lines(
|
|
2781
|
+
HashDelegator.join_code_lines(transient_code))
|
|
2776
2782
|
rescue Errno::ENOENT
|
|
2777
2783
|
report_error($ERROR_INFO)
|
|
2778
2784
|
end
|
|
@@ -2867,14 +2873,14 @@ module MarkdownExec
|
|
|
2867
2873
|
end
|
|
2868
2874
|
|
|
2869
2875
|
def execute_inherited_save(
|
|
2870
|
-
|
|
2876
|
+
transient_code: @dml_link_state.context_code
|
|
2871
2877
|
)
|
|
2872
2878
|
return unless (save_filespec = save_filespec_from_expression(
|
|
2873
2879
|
document_name_in_glob_as_file_name
|
|
2874
2880
|
))
|
|
2875
2881
|
|
|
2876
2882
|
unless write_file_with_directory_creation(
|
|
2877
|
-
content: HashDelegator.join_code_lines(
|
|
2883
|
+
content: HashDelegator.join_code_lines(transient_code),
|
|
2878
2884
|
filespec: save_filespec
|
|
2879
2885
|
)
|
|
2880
2886
|
:break
|
|
@@ -2885,14 +2891,14 @@ module MarkdownExec
|
|
|
2885
2891
|
@menu_user_clicked_back_link = true
|
|
2886
2892
|
|
|
2887
2893
|
keep_code = @dml_link_state.keep_code
|
|
2888
|
-
|
|
2894
|
+
context_code = keep_code ? @dml_link_state.context_code_block : nil
|
|
2889
2895
|
|
|
2890
2896
|
@dml_link_state = pop_link_history_new_state
|
|
2891
2897
|
|
|
2892
2898
|
{
|
|
2893
2899
|
block_name: @dml_link_state.block_name,
|
|
2894
2900
|
document_filename: @dml_link_state.document_filename,
|
|
2895
|
-
|
|
2901
|
+
context_code: context_code,
|
|
2896
2902
|
keep_code: keep_code
|
|
2897
2903
|
}
|
|
2898
2904
|
end
|
|
@@ -2908,23 +2914,25 @@ module MarkdownExec
|
|
|
2908
2914
|
def execute_required_lines(
|
|
2909
2915
|
blockname: '',
|
|
2910
2916
|
erls: {},
|
|
2911
|
-
|
|
2917
|
+
script_lines: [],
|
|
2912
2918
|
shell:
|
|
2913
2919
|
)
|
|
2914
2920
|
if @delegate_object[:save_executed_script]
|
|
2915
2921
|
write_command_file(blockname: blockname,
|
|
2916
|
-
required_lines:
|
|
2922
|
+
required_lines: script_lines,
|
|
2917
2923
|
shell: selected_shell(shell))
|
|
2918
2924
|
end
|
|
2919
2925
|
if @dml_block_state
|
|
2920
2926
|
calc_logged_stdout_filename(block_name: @dml_block_state.block.oname)
|
|
2921
2927
|
end
|
|
2922
2928
|
format_and_execute_command(
|
|
2923
|
-
|
|
2929
|
+
script_lines: script_lines,
|
|
2924
2930
|
erls: erls,
|
|
2925
2931
|
shell: selected_shell(shell)
|
|
2926
2932
|
)
|
|
2927
2933
|
post_execution_process
|
|
2934
|
+
rescue StandardError
|
|
2935
|
+
wwe $!
|
|
2928
2936
|
end
|
|
2929
2937
|
|
|
2930
2938
|
def expand_blocks_with_replacements(
|
|
@@ -3039,7 +3047,7 @@ module MarkdownExec
|
|
|
3039
3047
|
case export_string
|
|
3040
3048
|
when String, Integer, Float, TrueClass, FalseClass
|
|
3041
3049
|
command_result = HashDelegator.execute_bash_script_lines(
|
|
3042
|
-
|
|
3050
|
+
transient_code: join_array_of_arrays(
|
|
3043
3051
|
bash_script_lines,
|
|
3044
3052
|
printf_expand ? expander.call(export_string) : [export_string]
|
|
3045
3053
|
),
|
|
@@ -3080,7 +3088,7 @@ module MarkdownExec
|
|
|
3080
3088
|
# each item in the hash is a variable name and value
|
|
3081
3089
|
export_string.each do |name, expression|
|
|
3082
3090
|
command_result = HashDelegator.execute_bash_script_lines(
|
|
3083
|
-
|
|
3091
|
+
transient_code: join_array_of_arrays(
|
|
3084
3092
|
bash_script_lines,
|
|
3085
3093
|
required_lines,
|
|
3086
3094
|
printf_expand ? expander.call(expression) : [expression]
|
|
@@ -3211,11 +3219,11 @@ module MarkdownExec
|
|
|
3211
3219
|
end
|
|
3212
3220
|
|
|
3213
3221
|
def format_and_execute_command(
|
|
3214
|
-
|
|
3222
|
+
script_lines:,
|
|
3215
3223
|
erls:,
|
|
3216
3224
|
shell:
|
|
3217
3225
|
)
|
|
3218
|
-
formatted_command =
|
|
3226
|
+
formatted_command = script_lines.flatten.join("\n")
|
|
3219
3227
|
@fout.fout fetch_color(data_sym: :script_execution_head,
|
|
3220
3228
|
color_sym: :script_execution_frame_color)
|
|
3221
3229
|
|
|
@@ -3484,7 +3492,7 @@ module MarkdownExec
|
|
|
3484
3492
|
wwt :iterlines, 'nested_line:', nested_line
|
|
3485
3493
|
update_line_and_block_state(
|
|
3486
3494
|
nested_line, state, selected_types,
|
|
3487
|
-
source_id: "
|
|
3495
|
+
source_id: "IBNF:#{index}¤#{nested_line.filename}:#{nested_line.index}",
|
|
3488
3496
|
&block
|
|
3489
3497
|
)
|
|
3490
3498
|
|
|
@@ -3524,10 +3532,10 @@ module MarkdownExec
|
|
|
3524
3532
|
end.compact.flatten(1)
|
|
3525
3533
|
end
|
|
3526
3534
|
|
|
3527
|
-
def link_block_data_eval(link_state,
|
|
3535
|
+
def link_block_data_eval(link_state, transient_code, selected, link_block_data,
|
|
3528
3536
|
block_source:, shell:)
|
|
3529
3537
|
all_code = HashDelegator.flatten_and_compact_arrays(
|
|
3530
|
-
link_state&.
|
|
3538
|
+
link_state&.context_code, transient_code
|
|
3531
3539
|
)
|
|
3532
3540
|
output_lines = []
|
|
3533
3541
|
|
|
@@ -3546,34 +3554,34 @@ module MarkdownExec
|
|
|
3546
3554
|
output_lines.push(line) if line
|
|
3547
3555
|
end
|
|
3548
3556
|
|
|
3549
|
-
if link_block_data.fetch(LinkKeys::EVAL, true)
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3557
|
+
output_lines = if link_block_data.fetch(LinkKeys::EVAL, true)
|
|
3558
|
+
# eval: true
|
|
3559
|
+
|
|
3560
|
+
## select output_lines that look like assignment or match other specs
|
|
3561
|
+
#
|
|
3562
|
+
process_string_array(
|
|
3563
|
+
output_lines,
|
|
3564
|
+
begin_pattern: @delegate_object.fetch(:output_assignment_begin,
|
|
3565
|
+
nil),
|
|
3566
|
+
end_pattern: @delegate_object.fetch(:output_assignment_end, nil),
|
|
3567
|
+
scan1: @delegate_object.fetch(:output_assignment_match, nil),
|
|
3568
|
+
format1: @delegate_object.fetch(:output_assignment_format, nil),
|
|
3569
|
+
name: ''
|
|
3570
|
+
)
|
|
3563
3571
|
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3572
|
+
else
|
|
3573
|
+
# eval: false
|
|
3574
|
+
|
|
3575
|
+
## select all output_lines
|
|
3576
|
+
#
|
|
3577
|
+
process_string_array(
|
|
3578
|
+
output_lines,
|
|
3579
|
+
begin_pattern: @delegate_object.fetch(:output_assignment_begin,
|
|
3580
|
+
nil),
|
|
3581
|
+
end_pattern: @delegate_object.fetch(:output_assignment_end, nil),
|
|
3582
|
+
name: ''
|
|
3583
|
+
)
|
|
3584
|
+
end
|
|
3577
3585
|
else
|
|
3578
3586
|
output_lines = `bash #{file.path}`.split("\n")
|
|
3579
3587
|
end
|
|
@@ -3620,7 +3628,7 @@ module MarkdownExec
|
|
|
3620
3628
|
|
|
3621
3629
|
def link_history_push_and_next(
|
|
3622
3630
|
curr_block_name:, curr_document_filename:,
|
|
3623
|
-
inherited_block_names:, inherited_dependencies:,
|
|
3631
|
+
inherited_block_names:, inherited_dependencies:, context_code:,
|
|
3624
3632
|
keep_code:,
|
|
3625
3633
|
next_block_name:, next_document_filename:,
|
|
3626
3634
|
next_keep_code:,
|
|
@@ -3632,7 +3640,7 @@ module MarkdownExec
|
|
|
3632
3640
|
document_filename: curr_document_filename,
|
|
3633
3641
|
inherited_block_names: inherited_block_names,
|
|
3634
3642
|
inherited_dependencies: inherited_dependencies,
|
|
3635
|
-
|
|
3643
|
+
context_code: context_code,
|
|
3636
3644
|
keep_code: keep_code
|
|
3637
3645
|
)
|
|
3638
3646
|
)
|
|
@@ -3643,7 +3651,7 @@ module MarkdownExec
|
|
|
3643
3651
|
document_filename: next_document_filename,
|
|
3644
3652
|
inherited_block_names: inherited_block_names,
|
|
3645
3653
|
inherited_dependencies: inherited_dependencies,
|
|
3646
|
-
|
|
3654
|
+
context_code: context_code,
|
|
3647
3655
|
keep_code: next_keep_code
|
|
3648
3656
|
)
|
|
3649
3657
|
)
|
|
@@ -3833,27 +3841,27 @@ module MarkdownExec
|
|
|
3833
3841
|
reload_blocks = true
|
|
3834
3842
|
end
|
|
3835
3843
|
|
|
3836
|
-
|
|
3844
|
+
link_state_context_code = link_state&.context_code || []
|
|
3837
3845
|
|
|
3838
3846
|
# return code resulting from evaluating all SHELL, UX, VARS blocks;
|
|
3839
3847
|
# each set in sequence; with its own order
|
|
3840
3848
|
#
|
|
3841
|
-
if (
|
|
3849
|
+
if (transient_code = inherited_lines_from_auto_blocks(
|
|
3842
3850
|
all_blocks,
|
|
3843
3851
|
default_only: true,
|
|
3844
3852
|
mdoc: mdoc,
|
|
3845
|
-
|
|
3853
|
+
context_code: link_state_context_code
|
|
3846
3854
|
))&.select_by(:empty?, false)&.compact&.count&.positive?
|
|
3847
|
-
wwt :
|
|
3855
|
+
wwt :transient_code, 'transient_code:', transient_code
|
|
3848
3856
|
|
|
3849
|
-
# prepend
|
|
3850
|
-
new_code =
|
|
3857
|
+
# prepend context code to new transient code
|
|
3858
|
+
new_code = link_state_context_code + transient_code
|
|
3851
3859
|
next_state_set_code(nil, link_state, new_code)
|
|
3852
|
-
link_state.
|
|
3860
|
+
link_state.context_code = new_code
|
|
3853
3861
|
|
|
3854
3862
|
reload_blocks = true
|
|
3855
3863
|
else
|
|
3856
|
-
link_state&.
|
|
3864
|
+
link_state&.context_code
|
|
3857
3865
|
end
|
|
3858
3866
|
|
|
3859
3867
|
if reload_blocks
|
|
@@ -4040,19 +4048,19 @@ module MarkdownExec
|
|
|
4040
4048
|
list[(index + 1) % list.size] # Get the next item, wrap around if at the end
|
|
4041
4049
|
end
|
|
4042
4050
|
|
|
4043
|
-
def next_state_append_code(selected, link_state,
|
|
4051
|
+
def next_state_append_code(selected, link_state, context_code:,
|
|
4044
4052
|
mode: LoadMode::APPEND)
|
|
4045
4053
|
next_state_set_code(
|
|
4046
4054
|
selected,
|
|
4047
4055
|
link_state,
|
|
4048
4056
|
HashDelegator.flatten_and_compact_arrays(
|
|
4049
|
-
mode == LoadMode::APPEND ? link_state&.
|
|
4050
|
-
|
|
4057
|
+
mode == LoadMode::APPEND ? link_state&.context_code : [],
|
|
4058
|
+
context_code.is_a?(Array) ? context_code : [] # no code for :ux_exec_prohibited
|
|
4051
4059
|
)
|
|
4052
4060
|
)
|
|
4053
4061
|
end
|
|
4054
4062
|
|
|
4055
|
-
def next_state_set_code(selected, link_state,
|
|
4063
|
+
def next_state_set_code(selected, link_state, context_code)
|
|
4056
4064
|
block_names = []
|
|
4057
4065
|
dependencies = {}
|
|
4058
4066
|
link_history_push_and_next(
|
|
@@ -4062,7 +4070,7 @@ module MarkdownExec
|
|
|
4062
4070
|
((link_state&.inherited_block_names || []) + block_names).sort.uniq,
|
|
4063
4071
|
inherited_dependencies:
|
|
4064
4072
|
(link_state&.inherited_dependencies || {}).merge(dependencies || {}), ### merge, not replace, key data
|
|
4065
|
-
|
|
4073
|
+
context_code: HashDelegator.flatten_and_compact_arrays(context_code),
|
|
4066
4074
|
keep_code: link_state&.keep_code,
|
|
4067
4075
|
next_block_name: '',
|
|
4068
4076
|
next_document_filename: @delegate_object[:filename],
|
|
@@ -4127,7 +4135,7 @@ module MarkdownExec
|
|
|
4127
4135
|
end
|
|
4128
4136
|
|
|
4129
4137
|
def pop_add_current_code_to_head_and_trigger_load(
|
|
4130
|
-
link_state, block_names,
|
|
4138
|
+
link_state, block_names, transient_code,
|
|
4131
4139
|
dependencies, selected, next_block_name: nil
|
|
4132
4140
|
)
|
|
4133
4141
|
pop = @link_history.pop # updatable
|
|
@@ -4139,9 +4147,9 @@ module MarkdownExec
|
|
|
4139
4147
|
(pop.inherited_block_names + block_names).sort.uniq,
|
|
4140
4148
|
inherited_dependencies:
|
|
4141
4149
|
dependencies.merge(pop.inherited_dependencies || {}), ### merge, not replace, key data
|
|
4142
|
-
|
|
4143
|
-
HashDelegator.flatten_and_compact_arrays(pop.
|
|
4144
|
-
|
|
4150
|
+
context_code:
|
|
4151
|
+
HashDelegator.flatten_and_compact_arrays(pop.context_code,
|
|
4152
|
+
transient_code)
|
|
4145
4153
|
)
|
|
4146
4154
|
@link_history.push(next_state)
|
|
4147
4155
|
|
|
@@ -4157,9 +4165,9 @@ module MarkdownExec
|
|
|
4157
4165
|
((link_state&.inherited_block_names || []) + block_names).sort.uniq,
|
|
4158
4166
|
inherited_dependencies:
|
|
4159
4167
|
(link_state&.inherited_dependencies || {}).merge(dependencies || {}), ### merge, not replace, key data
|
|
4160
|
-
|
|
4168
|
+
context_code:
|
|
4161
4169
|
HashDelegator.flatten_and_compact_arrays(
|
|
4162
|
-
link_state&.
|
|
4170
|
+
link_state&.context_code, transient_code
|
|
4163
4171
|
),
|
|
4164
4172
|
keep_code: link_state&.keep_code,
|
|
4165
4173
|
next_block_name: next_block_name,
|
|
@@ -4184,7 +4192,7 @@ module MarkdownExec
|
|
|
4184
4192
|
document_filename: pop.document_filename,
|
|
4185
4193
|
inherited_block_names: peek.inherited_block_names,
|
|
4186
4194
|
inherited_dependencies: peek.inherited_dependencies,
|
|
4187
|
-
|
|
4195
|
+
context_code: peek.context_code
|
|
4188
4196
|
)
|
|
4189
4197
|
end
|
|
4190
4198
|
|
|
@@ -4560,11 +4568,13 @@ module MarkdownExec
|
|
|
4560
4568
|
obj = {}
|
|
4561
4569
|
|
|
4562
4570
|
# concatenated body of all required blocks loaded a YAML
|
|
4571
|
+
|
|
4572
|
+
rc = execute_block_type_port_code_lines(
|
|
4573
|
+
mdoc: mdoc, selected: selected,
|
|
4574
|
+
link_state: link_state, block_source: {}
|
|
4575
|
+
)
|
|
4563
4576
|
data = (YAML.load(
|
|
4564
|
-
|
|
4565
|
-
mdoc: mdoc, selected: selected,
|
|
4566
|
-
link_state: link_state, block_source: {}
|
|
4567
|
-
).join("\n")
|
|
4577
|
+
rc[:context_code].join("\n")
|
|
4568
4578
|
) || {}).transform_keys(&:to_sym)
|
|
4569
4579
|
|
|
4570
4580
|
if selected.type == BlockType::OPTS
|
|
@@ -4764,7 +4774,7 @@ module MarkdownExec
|
|
|
4764
4774
|
filename: filename,
|
|
4765
4775
|
saved_asset_format:
|
|
4766
4776
|
shell_escape_asset_format(
|
|
4767
|
-
|
|
4777
|
+
transient_code: link_state&.context_code,
|
|
4768
4778
|
shell: selected_shell(@delegate_object[:shell])
|
|
4769
4779
|
)
|
|
4770
4780
|
).generate_name
|
|
@@ -4933,7 +4943,7 @@ module MarkdownExec
|
|
|
4933
4943
|
end
|
|
4934
4944
|
|
|
4935
4945
|
def shell_escape_asset_format(
|
|
4936
|
-
|
|
4946
|
+
transient_code:,
|
|
4937
4947
|
enable: @delegate_object[:shell_parameter_expansion],
|
|
4938
4948
|
raw: @delegate_object[:saved_asset_format],
|
|
4939
4949
|
shell:
|
|
@@ -4948,7 +4958,7 @@ module MarkdownExec
|
|
|
4948
4958
|
|
|
4949
4959
|
marker = Random.new.rand.to_s
|
|
4950
4960
|
|
|
4951
|
-
code = (
|
|
4961
|
+
code = (transient_code || []) + ["echo -n \"#{marker}#{raw}\""]
|
|
4952
4962
|
File.write filespec, HashDelegator.join_code_lines(code)
|
|
4953
4963
|
File.chmod 0o755, filespec
|
|
4954
4964
|
|
|
@@ -5484,10 +5494,10 @@ module MarkdownExec
|
|
|
5484
5494
|
end
|
|
5485
5495
|
|
|
5486
5496
|
def vux_edit_inherited
|
|
5487
|
-
edited = edit_text(@dml_link_state.
|
|
5497
|
+
edited = edit_text(@dml_link_state.context_code_block)
|
|
5488
5498
|
return unless edited
|
|
5489
5499
|
|
|
5490
|
-
@dml_link_state.
|
|
5500
|
+
@dml_link_state.context_code =
|
|
5491
5501
|
annotate_required_lines(
|
|
5492
5502
|
'blk:EDIT', edited.split("\n"), block_name: 'EDIT'
|
|
5493
5503
|
)
|
|
@@ -5707,7 +5717,7 @@ module MarkdownExec
|
|
|
5707
5717
|
def vux_load_code_files_into_state
|
|
5708
5718
|
return unless @menu_base_options[:load_code].present?
|
|
5709
5719
|
|
|
5710
|
-
@dml_link_state.
|
|
5720
|
+
@dml_link_state.context_code =
|
|
5711
5721
|
@menu_base_options[:load_code].split(':').map do |path|
|
|
5712
5722
|
File.readlines(path, chomp: true)
|
|
5713
5723
|
end.flatten(1)
|
|
@@ -5718,7 +5728,7 @@ module MarkdownExec
|
|
|
5718
5728
|
|
|
5719
5729
|
pop_add_current_code_to_head_and_trigger_load(
|
|
5720
5730
|
@dml_link_state, inherited_block_names,
|
|
5721
|
-
|
|
5731
|
+
transient_code, inherited_dependencies, selected
|
|
5722
5732
|
)
|
|
5723
5733
|
end
|
|
5724
5734
|
|
|
@@ -5727,7 +5737,7 @@ module MarkdownExec
|
|
|
5727
5737
|
document_name_in_glob_as_file_name
|
|
5728
5738
|
))
|
|
5729
5739
|
|
|
5730
|
-
@dml_link_state.
|
|
5740
|
+
@dml_link_state.context_code_append(
|
|
5731
5741
|
File.readlines(filespec, chomp: true)
|
|
5732
5742
|
)
|
|
5733
5743
|
end
|
|
@@ -5886,7 +5896,7 @@ module MarkdownExec
|
|
|
5886
5896
|
files = document_glob ? Dir.glob(document_glob) : []
|
|
5887
5897
|
@doc_saved_lines_files = files.count.positive? ? files : []
|
|
5888
5898
|
|
|
5889
|
-
lines_count = @dml_link_state.
|
|
5899
|
+
lines_count = @dml_link_state.context_code_count
|
|
5890
5900
|
|
|
5891
5901
|
# add menu items (glob, load, save) and enable selectively
|
|
5892
5902
|
if files.count.positive? || lines_count.positive?
|
|
@@ -6011,7 +6021,7 @@ module MarkdownExec
|
|
|
6011
6021
|
end
|
|
6012
6022
|
|
|
6013
6023
|
def vux_view_inherited(stream:)
|
|
6014
|
-
stream.puts @dml_link_state.
|
|
6024
|
+
stream.puts @dml_link_state.context_code_block
|
|
6015
6025
|
end
|
|
6016
6026
|
|
|
6017
6027
|
def wait_for_stream_processing
|
|
@@ -6104,7 +6114,7 @@ module MarkdownExec
|
|
|
6104
6114
|
prefix: @delegate_object[:saved_script_filename_prefix],
|
|
6105
6115
|
saved_asset_format:
|
|
6106
6116
|
shell_escape_asset_format(
|
|
6107
|
-
|
|
6117
|
+
transient_code: @dml_link_state.context_code,
|
|
6108
6118
|
shell: shell
|
|
6109
6119
|
),
|
|
6110
6120
|
time: time_now
|
|
@@ -6163,7 +6173,7 @@ module MarkdownExec
|
|
|
6163
6173
|
if save_filespec.present?
|
|
6164
6174
|
File.write(
|
|
6165
6175
|
save_filespec,
|
|
6166
|
-
HashDelegator.join_code_lines(link_state&.
|
|
6176
|
+
HashDelegator.join_code_lines(link_state&.context_code)
|
|
6167
6177
|
)
|
|
6168
6178
|
@delegate_object[:filename]
|
|
6169
6179
|
else
|
|
@@ -6346,7 +6356,7 @@ module MarkdownExec
|
|
|
6346
6356
|
LinkState.new(block_name: 'sample_block',
|
|
6347
6357
|
document_filename: 'sample_file',
|
|
6348
6358
|
inherited_dependencies: {},
|
|
6349
|
-
|
|
6359
|
+
context_code: ['# ', 'KEY="VALUE"'])
|
|
6350
6360
|
)
|
|
6351
6361
|
assert_equal expected_result,
|
|
6352
6362
|
@hd.execute_block_type_link_with_state(
|
|
@@ -6522,12 +6532,43 @@ module MarkdownExec
|
|
|
6522
6532
|
def test_execute_block_type_port_code_lines_with_vars
|
|
6523
6533
|
YAML.stubs(:load).returns({ 'key' => 'value' })
|
|
6524
6534
|
@mdoc.stubs(:collect_recursively_required_code)
|
|
6525
|
-
.returns({
|
|
6535
|
+
.returns({ context_code: [], transient_code: ['code line'] })
|
|
6526
6536
|
result = @hd.execute_block_type_port_code_lines(
|
|
6527
6537
|
mdoc: @mdoc, selected: @selected, block_source: {}
|
|
6528
6538
|
)
|
|
6529
6539
|
|
|
6530
|
-
assert_equal ['
|
|
6540
|
+
assert_equal ['key="value"'], result[:context_code]
|
|
6541
|
+
assert_equal ['code line'], result[:transient_code]
|
|
6542
|
+
end
|
|
6543
|
+
|
|
6544
|
+
def test_transient_code_parameter_usage
|
|
6545
|
+
# Test that transient_code parameter is used correctly in execute_bash_script_lines
|
|
6546
|
+
transient_code = ["echo 'test'", "echo 'transient'"]
|
|
6547
|
+
export = OpenStruct.new(exportable: false, validate: //, transform: ->(x) { x })
|
|
6548
|
+
result = HashDelegator.execute_bash_script_lines(
|
|
6549
|
+
transient_code: transient_code,
|
|
6550
|
+
export: export,
|
|
6551
|
+
export_name: 'TEST',
|
|
6552
|
+
shell: '/bin/bash'
|
|
6553
|
+
)
|
|
6554
|
+
|
|
6555
|
+
assert result.is_a?(CommandResult)
|
|
6556
|
+
assert_equal transient_code, result.script
|
|
6557
|
+
end
|
|
6558
|
+
|
|
6559
|
+
def test_transient_code_vs_context_code_separation
|
|
6560
|
+
# Test that transient_code is separate from context_code
|
|
6561
|
+
context_code = ['CONTEXT_VAR="context_value"']
|
|
6562
|
+
transient_code = ['TRANSIENT_VAR="transient_value"']
|
|
6563
|
+
|
|
6564
|
+
# Simulate combining them
|
|
6565
|
+
all_code = HashDelegator.flatten_and_compact_arrays(
|
|
6566
|
+
context_code, transient_code
|
|
6567
|
+
)
|
|
6568
|
+
|
|
6569
|
+
assert_equal 2, all_code.length
|
|
6570
|
+
assert_includes all_code, 'CONTEXT_VAR="context_value"'
|
|
6571
|
+
assert_includes all_code, 'TRANSIENT_VAR="transient_value"'
|
|
6531
6572
|
end
|
|
6532
6573
|
end
|
|
6533
6574
|
|