markdown_exec 2.8.1 → 2.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +53 -0
- data/Gemfile.lock +1 -1
- data/bats/block-hide.bats +8 -0
- data/bats/block-type-ux-echo.bats +20 -0
- data/bats/block-type-ux-preconditions.bats +8 -0
- data/bats/block-type-ux-readonly.bats +10 -0
- data/bats/block-type-ux-require.bats +8 -0
- data/bats/block-type-vars.bats +3 -3
- data/bats/indented-multi-line-output.bats +9 -0
- data/bats/line-decor-dynamic.bats +8 -0
- data/bats/test_helper.bash +10 -0
- data/bin/tab_completion.sh +0 -5
- data/bin/tab_completion.sh.erb +0 -5
- data/docs/dev/block-hide.md +18 -0
- data/docs/dev/block-type-ux-echo.md +21 -0
- data/docs/dev/block-type-ux-preconditions.md +9 -0
- data/docs/dev/block-type-ux-readonly.md +7 -0
- data/docs/dev/block-type-ux-require.md +32 -0
- data/docs/dev/indented-multi-line-output.md +11 -0
- data/docs/dev/line-decor-dynamic.md +9 -0
- data/lib/ansi_string.rb +10 -1
- data/lib/fcb.rb +20 -5
- data/lib/filter.rb +3 -2
- data/lib/hash_delegator.rb +358 -274
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +11 -28
- data/lib/mdoc.rb +5 -6
- data/lib/menu.src.yml +1 -0
- data/lib/menu.yml +1 -0
- metadata +16 -2
data/lib/hash_delegator.rb
CHANGED
@@ -306,7 +306,7 @@ module HashDelegatorSelf
|
|
306
306
|
table__hs.each do |table_hs|
|
307
307
|
table_hs.substrings.each do |substrings|
|
308
308
|
substrings.each do |node|
|
309
|
-
next unless node[:text].
|
309
|
+
next unless node[:text].instance_of?(TrackedString)
|
310
310
|
|
311
311
|
exceeded_table_cell ||= node[:text].exceeded
|
312
312
|
truncated_table_cell = node[:text].truncated
|
@@ -395,10 +395,17 @@ module HashDelegatorSelf
|
|
395
395
|
# @param [String] line The line to be processed.
|
396
396
|
# @param [Array<Symbol>] selected_types A list of message types to check.
|
397
397
|
# @param [Proc] block The block to be called with the line data.
|
398
|
-
def yield_line_if_selected(line, selected_types,
|
398
|
+
def yield_line_if_selected(line, selected_types, all_fcbs: nil,
|
399
|
+
source_id: '', &block)
|
399
400
|
return unless block && block_type_selected?(selected_types, :line)
|
400
401
|
|
401
|
-
block.call(:line,
|
402
|
+
block.call(:line, persist_fcb_self(all_fcbs, body: [line], id: source_id))
|
403
|
+
end
|
404
|
+
|
405
|
+
def persist_fcb_self(all_fcbs, options)
|
406
|
+
fcb = MarkdownExec::FCB.new(options)
|
407
|
+
all_fcbs << fcb if all_fcbs
|
408
|
+
fcb
|
402
409
|
end
|
403
410
|
end
|
404
411
|
|
@@ -606,6 +613,10 @@ module MarkdownExec
|
|
606
613
|
|
607
614
|
@process_mutex = Mutex.new
|
608
615
|
@process_cv = ConditionVariable.new
|
616
|
+
@dml_link_state = Struct.new(:document_filename, :inherited_lines)
|
617
|
+
.new(@delegate_object[:filename], [])
|
618
|
+
@dml_menu_blocks = []
|
619
|
+
@fcb_store = [] # all fcbs created
|
609
620
|
|
610
621
|
@p_all_arguments = []
|
611
622
|
@p_options_parsed = []
|
@@ -734,7 +745,7 @@ module MarkdownExec
|
|
734
745
|
|
735
746
|
formatted_name = format(@delegate_object[:menu_link_format],
|
736
747
|
HashDelegator.safeval(option_name))
|
737
|
-
chrome_block =
|
748
|
+
chrome_block = persist_fcb(
|
738
749
|
chrome: true,
|
739
750
|
dname: HashDelegator.new(@delegate_object).string_send_color(
|
740
751
|
formatted_name, :menu_chrome_color
|
@@ -778,7 +789,7 @@ module MarkdownExec
|
|
778
789
|
chrome_blocks = link_state.inherited_lines_map do |line|
|
779
790
|
formatted = format(@delegate_object[:menu_inherited_lines_format],
|
780
791
|
{ line: line })
|
781
|
-
|
792
|
+
persist_fcb(
|
782
793
|
chrome: true,
|
783
794
|
disabled: TtyMenu::DISABLE,
|
784
795
|
dname: HashDelegator.new(@delegate_object).string_send_color(
|
@@ -837,25 +848,6 @@ module MarkdownExec
|
|
837
848
|
end
|
838
849
|
end
|
839
850
|
|
840
|
-
# private
|
841
|
-
|
842
|
-
def expand_references!(fcb, link_state)
|
843
|
-
expand_variable_references!(
|
844
|
-
blocks: [fcb],
|
845
|
-
initial_code_required: false,
|
846
|
-
link_state: link_state
|
847
|
-
)
|
848
|
-
expand_variable_references!(
|
849
|
-
blocks: [fcb],
|
850
|
-
echo_format: '%s',
|
851
|
-
group_name: :command,
|
852
|
-
initial_code_required: false,
|
853
|
-
key_format: '$(%s)',
|
854
|
-
link_state: link_state,
|
855
|
-
pattern: options_command_substitution_regexp
|
856
|
-
)
|
857
|
-
end
|
858
|
-
|
859
851
|
# Iterates through nested files to collect various types
|
860
852
|
# of blocks, including dividers, tasks, and others.
|
861
853
|
# The method categorizes blocks based on their type and processes them accordingly.
|
@@ -910,30 +902,6 @@ module MarkdownExec
|
|
910
902
|
HashDelegator.error_handler('blocks_from_nested_files')
|
911
903
|
end
|
912
904
|
|
913
|
-
# find a block by its original (undecorated) name or nickname (not visible in menu)
|
914
|
-
# if matched, the block returned has properties that it is from cli and not ui
|
915
|
-
def block_state_for_name_from_cli(block_name)
|
916
|
-
SelectedBlockMenuState.new(
|
917
|
-
blocks_find_by_block_name(@dml_blocks_in_file, block_name),
|
918
|
-
OpenStruct.new(
|
919
|
-
block_name_from_cli: true,
|
920
|
-
block_name_from_ui: false
|
921
|
-
),
|
922
|
-
MenuState::CONTINUE
|
923
|
-
)
|
924
|
-
end
|
925
|
-
|
926
|
-
def blocks_find_by_block_name(blocks, block_name)
|
927
|
-
@dml_blocks_in_file.find do |item|
|
928
|
-
# 2024-08-04 match oname for long block names
|
929
|
-
# 2024-08-04 match nickname for long block names
|
930
|
-
block_name == item.pub_name || block_name == item.nickname || block_name == item.oname
|
931
|
-
end || @dml_menu_blocks.find do |item|
|
932
|
-
# 2024-08-22 search in menu blocks to allow matching of automatic chrome with nickname
|
933
|
-
block_name == item.pub_name || block_name == item.nickname || block_name == item.oname
|
934
|
-
end
|
935
|
-
end
|
936
|
-
|
937
905
|
def build_menu_options(exit_option, display_mode_option,
|
938
906
|
menu_entries, display_format)
|
939
907
|
[exit_option,
|
@@ -1022,25 +990,11 @@ module MarkdownExec
|
|
1022
990
|
]
|
1023
991
|
end
|
1024
992
|
|
1025
|
-
|
1026
|
-
|
1027
|
-
# ww0 inherited_code
|
1028
|
-
code = (inherited_code || []) + [export_exec]
|
1029
|
-
filespec = generate_temp_filename
|
1030
|
-
File.write filespec, HashDelegator.join_code_lines(code)
|
1031
|
-
File.chmod 0o755, filespec
|
1032
|
-
# ww0 File.read(filespec)
|
1033
|
-
ret = `#{filespec}`
|
1034
|
-
File.delete filespec
|
1035
|
-
ret
|
1036
|
-
end
|
1037
|
-
|
1038
|
-
# sets ENV
|
993
|
+
# parse YAML body defining the UX for a single variable
|
994
|
+
# set ENV value for the variable and return code lines for the same
|
1039
995
|
def code_from_ux_block_to_set_environment_variables(
|
1040
996
|
selected, mdoc, inherited_code: nil, force: true, only_default: false
|
1041
997
|
)
|
1042
|
-
# ww0 inherited_code
|
1043
|
-
# ww0 mdoc
|
1044
998
|
exit_prompt = @delegate_object[:prompt_filespec_back]
|
1045
999
|
|
1046
1000
|
required = mdoc.collect_recursively_required_code(
|
@@ -1050,105 +1004,129 @@ module MarkdownExec
|
|
1050
1004
|
block_source: block_source
|
1051
1005
|
)
|
1052
1006
|
|
1007
|
+
# process each ux block in sequence, setting ENV and collecting lines
|
1053
1008
|
code_lines = []
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1009
|
+
required[:blocks].each do |block|
|
1010
|
+
next unless block.type == BlockType::UX
|
1011
|
+
|
1012
|
+
case data = YAML.load(block.body.join("\n"))
|
1013
|
+
when Hash
|
1014
|
+
export = parse_yaml_of_ux_block(
|
1015
|
+
data,
|
1016
|
+
prompt: @delegate_object[:prompt_ux_enter_a_value],
|
1017
|
+
validate: '^(?<name>[^ ].*)$'
|
1018
|
+
)
|
1019
|
+
|
1020
|
+
# preconditions are variable names that must be set before the UX block is executed.
|
1021
|
+
# if any precondition is not set, the sequence is aborted.
|
1022
|
+
export.preconditions&.each do |precondition|
|
1023
|
+
code_lines.push "[[ -z $#{precondition} ]] && exit 1"
|
1024
|
+
end
|
1061
1025
|
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1026
|
+
exportable = true
|
1027
|
+
if only_default
|
1028
|
+
value = case export.default
|
1029
|
+
# echo > default
|
1030
|
+
when :echo
|
1031
|
+
raise unless export.echo.present?
|
1032
|
+
|
1033
|
+
output = export_echo_with_code(
|
1034
|
+
export, inherited_code, code_lines, required
|
1035
|
+
)
|
1036
|
+
if output == :invalidated
|
1037
|
+
return :ux_exec_prohibited
|
1038
|
+
end
|
1068
1039
|
|
1069
|
-
|
1070
|
-
(inherited_code || []) + required[:code])
|
1040
|
+
transform_export_value(output, export)
|
1071
1041
|
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
)
|
1042
|
+
# exec > default
|
1043
|
+
when :exec
|
1044
|
+
raise unless export.exec.present?
|
1045
|
+
|
1046
|
+
output = export_exec_with_code(
|
1047
|
+
export, inherited_code, code_lines, required
|
1048
|
+
)
|
1049
|
+
if output == :invalidated
|
1050
|
+
return :ux_exec_prohibited
|
1082
1051
|
end
|
1052
|
+
|
1053
|
+
transform_export_value(output, export)
|
1054
|
+
|
1055
|
+
# default
|
1083
1056
|
else
|
1084
|
-
|
1057
|
+
export.default.to_s
|
1085
1058
|
end
|
1059
|
+
else
|
1060
|
+
value = nil
|
1086
1061
|
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
# exec > allowed
|
1096
|
-
if export.exec
|
1097
|
-
value = neval(export.exec, (inherited_code || []) + required[:code])
|
1098
|
-
caps = NamedCaptureExtractor.extract_named_groups(value,
|
1099
|
-
export.validate)
|
1100
|
-
|
1101
|
-
# allowed > prompt
|
1102
|
-
elsif export.allowed && export.allowed.count.positive?
|
1103
|
-
case (choice = prompt_select_code_filename(
|
1104
|
-
[exit_prompt] + export.allowed,
|
1105
|
-
string: export.prompt,
|
1106
|
-
color_sym: :prompt_color_after_script_execution
|
1107
|
-
))
|
1108
|
-
when exit_prompt
|
1109
|
-
exportable = false
|
1110
|
-
else
|
1111
|
-
value = choice
|
1112
|
-
caps = NamedCaptureExtractor.extract_named_groups(value,
|
1113
|
-
export.validate)
|
1114
|
-
end
|
1062
|
+
# echo > exec
|
1063
|
+
if export.echo
|
1064
|
+
value = export_echo_with_code(
|
1065
|
+
export, inherited_code, code_lines, required
|
1066
|
+
)
|
1067
|
+
if value == :invalidated
|
1068
|
+
return :ux_exec_prohibited
|
1069
|
+
end
|
1115
1070
|
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
export.validate)
|
1125
|
-
break if caps
|
1071
|
+
# exec > allowed
|
1072
|
+
elsif export.exec
|
1073
|
+
value = export_exec_with_code(
|
1074
|
+
export, inherited_code, code_lines, required
|
1075
|
+
)
|
1076
|
+
if value == :invalidated
|
1077
|
+
return :ux_exec_prohibited
|
1078
|
+
end
|
1126
1079
|
|
1127
|
-
|
1080
|
+
# allowed > prompt
|
1081
|
+
elsif export.allowed && export.allowed.count.positive?
|
1082
|
+
case (choice = prompt_select_code_filename(
|
1083
|
+
[exit_prompt] + export.allowed,
|
1084
|
+
string: export.prompt,
|
1085
|
+
color_sym: :prompt_color_after_script_execution
|
1086
|
+
))
|
1087
|
+
when exit_prompt
|
1088
|
+
exportable = false
|
1089
|
+
else
|
1090
|
+
value = choice
|
1091
|
+
end
|
1128
1092
|
|
1093
|
+
# prompt > default
|
1094
|
+
elsif export.prompt.present?
|
1095
|
+
begin
|
1096
|
+
loop do
|
1097
|
+
print "#{export.prompt} [#{export.default}]: "
|
1098
|
+
value = gets.chomp
|
1099
|
+
value = export.default.to_s if value.empty?
|
1100
|
+
caps = NamedCaptureExtractor.extract_named_groups(value,
|
1101
|
+
export.validate)
|
1102
|
+
break if caps
|
1103
|
+
|
1104
|
+
# invalid input, retry
|
1105
|
+
end
|
1106
|
+
rescue Interrupt
|
1107
|
+
exportable = false
|
1129
1108
|
end
|
1130
|
-
|
1131
|
-
|
1109
|
+
|
1110
|
+
# default
|
1111
|
+
else
|
1112
|
+
value = export.default
|
1132
1113
|
end
|
1133
1114
|
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1115
|
+
if exportable
|
1116
|
+
value = transform_export_value(value, export)
|
1117
|
+
end
|
1137
1118
|
end
|
1138
1119
|
|
1139
|
-
if exportable
|
1140
|
-
|
1120
|
+
if exportable
|
1121
|
+
ENV[export.name] = value.to_s
|
1122
|
+
code_lines.push code_line_safe_assign(export.name, value,
|
1123
|
+
force: force)
|
1141
1124
|
end
|
1125
|
+
else
|
1126
|
+
raise "Invalid data type: #{data.inspect}"
|
1142
1127
|
end
|
1143
|
-
|
1144
|
-
if exportable
|
1145
|
-
ENV[export.name] = value.to_s
|
1146
|
-
code_lines.push code_line_safe_assign(export.name, value,
|
1147
|
-
force: force)
|
1148
|
-
end
|
1149
|
-
else
|
1150
|
-
raise "Invalid data type: #{data.inspect}"
|
1151
1128
|
end
|
1129
|
+
|
1152
1130
|
code_lines
|
1153
1131
|
end
|
1154
1132
|
|
@@ -1221,7 +1199,8 @@ module MarkdownExec
|
|
1221
1199
|
command_execute_in_process(
|
1222
1200
|
args: args, command: command,
|
1223
1201
|
erls: erls,
|
1224
|
-
filename: @delegate_object[:filename],
|
1202
|
+
filename: @delegate_object[:filename],
|
1203
|
+
shell: shell
|
1225
1204
|
)
|
1226
1205
|
end
|
1227
1206
|
|
@@ -1285,7 +1264,8 @@ module MarkdownExec
|
|
1285
1264
|
)
|
1286
1265
|
execute_command_with_streams(
|
1287
1266
|
[shell, '-c', command,
|
1288
|
-
@delegate_object[:filename],
|
1267
|
+
@delegate_object[:filename],
|
1268
|
+
*args]
|
1289
1269
|
)
|
1290
1270
|
end
|
1291
1271
|
|
@@ -1390,7 +1370,7 @@ module MarkdownExec
|
|
1390
1370
|
next if exclude_types.include?(block.type)
|
1391
1371
|
|
1392
1372
|
# Scan each block name for matches of the pattern
|
1393
|
-
(
|
1373
|
+
count_named_group_occurrences_block_body_fix_indent(block).scan(pattern) do |(_, _variable_name)|
|
1394
1374
|
pattern.match($LAST_MATCH_INFO.to_s) # Reapply match for named groups
|
1395
1375
|
occurrence_count[$LAST_MATCH_INFO[group_name]] += 1
|
1396
1376
|
end
|
@@ -1399,6 +1379,11 @@ module MarkdownExec
|
|
1399
1379
|
occurrence_count
|
1400
1380
|
end
|
1401
1381
|
|
1382
|
+
def count_named_group_occurrences_block_body_fix_indent(block)
|
1383
|
+
### actually double the entries, but not a problem since it's used as a boolean
|
1384
|
+
([block.oname || ''] + block.body).join("\n")
|
1385
|
+
end
|
1386
|
+
|
1402
1387
|
##
|
1403
1388
|
# Creates and adds a formatted block to the blocks array
|
1404
1389
|
# based on the provided match and format options.
|
@@ -1500,7 +1485,7 @@ module MarkdownExec
|
|
1500
1485
|
fcb.type = type
|
1501
1486
|
use_fcb = false # next line is new record
|
1502
1487
|
else
|
1503
|
-
fcb =
|
1488
|
+
fcb = persist_fcb(
|
1504
1489
|
center: center,
|
1505
1490
|
chrome: true,
|
1506
1491
|
collapse: collapse.nil? ? (line_obj[:collapse] == COLLAPSIBLE_TOKEN_COLLAPSE) : collapse,
|
@@ -1587,7 +1572,7 @@ module MarkdownExec
|
|
1587
1572
|
oname = format(@delegate_object[:menu_divider_format],
|
1588
1573
|
HashDelegator.safeval(@delegate_object[divider_key]))
|
1589
1574
|
|
1590
|
-
|
1575
|
+
persist_fcb(
|
1591
1576
|
chrome: true,
|
1592
1577
|
disabled: TtyMenu::DISABLE,
|
1593
1578
|
dname: string_send_color(oname, :menu_divider_color),
|
@@ -1987,9 +1972,7 @@ module MarkdownExec
|
|
1987
1972
|
)
|
1988
1973
|
|
1989
1974
|
# dname is not fixed for some block types, use block id
|
1990
|
-
if lfls.load_file != LoadFile::LOAD
|
1991
|
-
[BlockType::HEADING, BlockType::TEXT,
|
1992
|
-
BlockType::UX].include?(selected.type)
|
1975
|
+
if lfls.load_file != LoadFile::LOAD
|
1993
1976
|
block_selection = BlockSelection.new(selected.id)
|
1994
1977
|
end
|
1995
1978
|
|
@@ -1999,7 +1982,7 @@ module MarkdownExec
|
|
1999
1982
|
end
|
2000
1983
|
|
2001
1984
|
def execute_block_in_state(block_name)
|
2002
|
-
@dml_block_state =
|
1985
|
+
@dml_block_state = find_block_state_by_name(block_name)
|
2003
1986
|
dump_and_warn_block_state(name: block_name,
|
2004
1987
|
selected: @dml_block_state.block)
|
2005
1988
|
next_block_state =
|
@@ -2173,24 +2156,24 @@ module MarkdownExec
|
|
2173
2156
|
else
|
2174
2157
|
warn 'No matching file found.'
|
2175
2158
|
end
|
2176
|
-
elsif selected_option = select_option_with_metadata(
|
2159
|
+
elsif (selected_option = select_option_with_metadata(
|
2177
2160
|
prompt_title,
|
2178
2161
|
[exit_prompt] + dirs.map do |file|
|
2179
|
-
{ name:
|
2180
|
-
|
2181
|
-
|
2182
|
-
|
2183
|
-
|
2184
|
-
|
2185
|
-
|
2186
|
-
|
2187
|
-
|
2162
|
+
{ name:
|
2163
|
+
format(
|
2164
|
+
block_data['view'] || view,
|
2165
|
+
NamedCaptureExtractor.extract_named_group_match_data(
|
2166
|
+
file.match(
|
2167
|
+
Regexp.new(block_data['filename_pattern'] || filename_pattern)
|
2168
|
+
)
|
2169
|
+
)
|
2170
|
+
),
|
2188
2171
|
oname: file }
|
2189
2172
|
end,
|
2190
2173
|
menu_options.merge(
|
2191
2174
|
cycle: true
|
2192
2175
|
)
|
2193
|
-
)
|
2176
|
+
))
|
2194
2177
|
if selected_option.dname != exit_prompt
|
2195
2178
|
File.readlines(selected_option.oname, chomp: true)
|
2196
2179
|
end
|
@@ -2341,7 +2324,7 @@ module MarkdownExec
|
|
2341
2324
|
|
2342
2325
|
interactive_menu_with_display_modes(
|
2343
2326
|
files_table_rows,
|
2344
|
-
display_formats: [
|
2327
|
+
display_formats: %i[row file],
|
2345
2328
|
display_mode_option: @delegate_object[:prompt_filespec_facet],
|
2346
2329
|
exit_option: exit_prompt,
|
2347
2330
|
menu_title: @delegate_object[:prompt_select_history_file],
|
@@ -2364,9 +2347,9 @@ module MarkdownExec
|
|
2364
2347
|
def execute_inherited_save(
|
2365
2348
|
code_lines: @dml_link_state.inherited_lines
|
2366
2349
|
)
|
2367
|
-
return unless save_filespec = save_filespec_from_expression
|
2368
|
-
|
2369
|
-
|
2350
|
+
return unless (save_filespec = save_filespec_from_expression)
|
2351
|
+
|
2352
|
+
document_name_in_glob_as_file_name
|
2370
2353
|
|
2371
2354
|
unless write_file_with_directory_creation(
|
2372
2355
|
content: HashDelegator.join_code_lines(code_lines),
|
@@ -2422,6 +2405,27 @@ module MarkdownExec
|
|
2422
2405
|
post_execution_process
|
2423
2406
|
end
|
2424
2407
|
|
2408
|
+
def execute_temporary_script(script_code, additional_code = [])
|
2409
|
+
full_code = (additional_code || []) + [script_code]
|
2410
|
+
|
2411
|
+
Tempfile.create('script_exec') do |temp_file|
|
2412
|
+
temp_file.write(HashDelegator.join_code_lines(full_code))
|
2413
|
+
temp_file.flush
|
2414
|
+
File.chmod(0o755, temp_file.path)
|
2415
|
+
|
2416
|
+
output = `#{temp_file.path}`
|
2417
|
+
|
2418
|
+
if $?.exitstatus != 0
|
2419
|
+
return :invalidated
|
2420
|
+
end
|
2421
|
+
|
2422
|
+
output
|
2423
|
+
end
|
2424
|
+
rescue StandardError => err
|
2425
|
+
warn "Error executing script: #{err.message}"
|
2426
|
+
nil
|
2427
|
+
end
|
2428
|
+
|
2425
2429
|
def expand_blocks_with_replacements(
|
2426
2430
|
menu_blocks, replacements, exclude_types: [BlockType::SHELL]
|
2427
2431
|
)
|
@@ -2438,6 +2442,23 @@ module MarkdownExec
|
|
2438
2442
|
end
|
2439
2443
|
end
|
2440
2444
|
|
2445
|
+
def expand_references!(fcb, link_state)
|
2446
|
+
expand_variable_references!(
|
2447
|
+
blocks: [fcb],
|
2448
|
+
initial_code_required: false,
|
2449
|
+
link_state: link_state
|
2450
|
+
)
|
2451
|
+
expand_variable_references!(
|
2452
|
+
blocks: [fcb],
|
2453
|
+
echo_format: '%s',
|
2454
|
+
group_name: :command,
|
2455
|
+
initial_code_required: false,
|
2456
|
+
key_format: '$(%s)',
|
2457
|
+
link_state: link_state,
|
2458
|
+
pattern: options_command_substitution_regexp
|
2459
|
+
)
|
2460
|
+
end
|
2461
|
+
|
2441
2462
|
def expand_variable_references!(
|
2442
2463
|
blocks:,
|
2443
2464
|
echo_format: 'echo $%s',
|
@@ -2468,6 +2489,30 @@ module MarkdownExec
|
|
2468
2489
|
expand_blocks_with_replacements(blocks, replacements)
|
2469
2490
|
end
|
2470
2491
|
|
2492
|
+
def export_echo_with_code(export, inherited_code, code_lines, required)
|
2493
|
+
value = execute_temporary_script(
|
2494
|
+
%Q{eval printf '%s' "#{export.echo}"},
|
2495
|
+
(inherited_code || []) +
|
2496
|
+
code_lines + required[:code]
|
2497
|
+
)
|
2498
|
+
if value == :invalidated
|
2499
|
+
warn "A value must exist for: #{export.preconditions.join(', ')}"
|
2500
|
+
end
|
2501
|
+
value
|
2502
|
+
end
|
2503
|
+
|
2504
|
+
def export_exec_with_code(export, inherited_code, code_lines, required)
|
2505
|
+
value = execute_temporary_script(
|
2506
|
+
export.exec,
|
2507
|
+
(inherited_code || []) +
|
2508
|
+
code_lines + required[:code]
|
2509
|
+
)
|
2510
|
+
if value == :invalidated
|
2511
|
+
warn "A value must exist for: #{export.preconditions.join(', ')}"
|
2512
|
+
end
|
2513
|
+
value
|
2514
|
+
end
|
2515
|
+
|
2471
2516
|
# Retrieves a specific data symbol from the delegate object,
|
2472
2517
|
# converts it to a string, and applies a color style
|
2473
2518
|
# based on the specified color symbol.
|
@@ -2501,6 +2546,31 @@ module MarkdownExec
|
|
2501
2546
|
{ size: file_size, lines: line_count }
|
2502
2547
|
end
|
2503
2548
|
|
2549
|
+
# Search in @dml_blocks_in_file first,
|
2550
|
+
# fallback to @dml_menu_blocks if not found.
|
2551
|
+
def find_block_by_name(blocks, block_name)
|
2552
|
+
match_block = ->(item) do
|
2553
|
+
[item.pub_name, item.nickname,
|
2554
|
+
item.oname, item.s2title].include?(block_name)
|
2555
|
+
end
|
2556
|
+
|
2557
|
+
@dml_blocks_in_file.find(&match_block) ||
|
2558
|
+
@dml_menu_blocks.find(&match_block)
|
2559
|
+
end
|
2560
|
+
|
2561
|
+
# find a block by its original (undecorated) name or nickname (not visible in menu)
|
2562
|
+
# if matched, the block returned has properties that it is from cli and not ui
|
2563
|
+
def find_block_state_by_name(block_name)
|
2564
|
+
SelectedBlockMenuState.new(
|
2565
|
+
find_block_by_name(@dml_blocks_in_file, block_name),
|
2566
|
+
OpenStruct.new(
|
2567
|
+
block_name_from_cli: true,
|
2568
|
+
block_name_from_ui: false
|
2569
|
+
),
|
2570
|
+
MenuState::CONTINUE
|
2571
|
+
)
|
2572
|
+
end
|
2573
|
+
|
2504
2574
|
def format_and_execute_command(
|
2505
2575
|
code_lines:,
|
2506
2576
|
erls:,
|
@@ -2509,6 +2579,7 @@ module MarkdownExec
|
|
2509
2579
|
formatted_command = code_lines.flatten.join("\n")
|
2510
2580
|
@fout.fout fetch_color(data_sym: :script_execution_head,
|
2511
2581
|
color_sym: :script_execution_frame_color)
|
2582
|
+
|
2512
2583
|
command_execute(
|
2513
2584
|
formatted_command,
|
2514
2585
|
args: @pass_args,
|
@@ -2580,7 +2651,7 @@ module MarkdownExec
|
|
2580
2651
|
# commands to echo variables
|
2581
2652
|
#
|
2582
2653
|
commands = {}
|
2583
|
-
variable_counts.
|
2654
|
+
variable_counts.each_key do |variable|
|
2584
2655
|
command = format(echo_format, variable)
|
2585
2656
|
commands[variable] = command
|
2586
2657
|
end
|
@@ -2618,10 +2689,8 @@ module MarkdownExec
|
|
2618
2689
|
@process_mutex.synchronize do
|
2619
2690
|
Thread.new do
|
2620
2691
|
stream.each_line do |line|
|
2621
|
-
line.strip!
|
2622
2692
|
if @run_state.files.streams
|
2623
|
-
@run_state.files.append_stream_line(file_type,
|
2624
|
-
line)
|
2693
|
+
@run_state.files.append_stream_line(file_type, line)
|
2625
2694
|
end
|
2626
2695
|
|
2627
2696
|
puts line if @delegate_object[:output_stdout]
|
@@ -2637,7 +2706,6 @@ module MarkdownExec
|
|
2637
2706
|
end
|
2638
2707
|
|
2639
2708
|
def history_files(
|
2640
|
-
link_state,
|
2641
2709
|
direction: :reverse,
|
2642
2710
|
filename: nil,
|
2643
2711
|
home: Dir.pwd,
|
@@ -2670,7 +2738,7 @@ module MarkdownExec
|
|
2670
2738
|
Regexp.new(@delegate_object.fetch(
|
2671
2739
|
:fenced_start_and_end_regex, '^(?<indent> *)`{3,}'
|
2672
2740
|
)),
|
2673
|
-
fcb:
|
2741
|
+
fcb: persist_fcb(id: 'INIT'),
|
2674
2742
|
in_fenced_block: false,
|
2675
2743
|
headings: []
|
2676
2744
|
}
|
@@ -2950,19 +3018,24 @@ module MarkdownExec
|
|
2950
3018
|
@ux_most_recent_filename = @delegate_object[:filename]
|
2951
3019
|
|
2952
3020
|
(blocks.each.with_object([]) do |block, merged_options|
|
2953
|
-
|
2954
|
-
|
2955
|
-
|
2956
|
-
|
2957
|
-
|
2958
|
-
only_default: true
|
2959
|
-
)
|
3021
|
+
code = code_from_ux_block_to_set_environment_variables(
|
3022
|
+
block,
|
3023
|
+
mdoc,
|
3024
|
+
force: @delegate_object[:ux_auto_load_force_default],
|
3025
|
+
only_default: true
|
2960
3026
|
)
|
3027
|
+
if code == :ux_exec_prohibited
|
3028
|
+
merged_options
|
3029
|
+
else
|
3030
|
+
merged_options.push(code)
|
3031
|
+
end
|
2961
3032
|
end).to_a
|
2962
3033
|
end
|
2963
3034
|
|
2964
|
-
def load_auto_vars_block(
|
2965
|
-
|
3035
|
+
def load_auto_vars_block(
|
3036
|
+
all_blocks,
|
3037
|
+
block_name: @delegate_object[:document_load_vars_block_name]
|
3038
|
+
)
|
2966
3039
|
unless block_name.present? &&
|
2967
3040
|
@vars_most_recent_filename != @delegate_object[:filename]
|
2968
3041
|
return
|
@@ -3103,7 +3176,7 @@ module MarkdownExec
|
|
3103
3176
|
|
3104
3177
|
# load document shell block
|
3105
3178
|
#
|
3106
|
-
if code_lines = load_document_shell_block(all_blocks, mdoc: mdoc)
|
3179
|
+
if (code_lines = load_document_shell_block(all_blocks, mdoc: mdoc))
|
3107
3180
|
next_state_set_code(nil, link_state, code_lines)
|
3108
3181
|
link_state.inherited_lines = code_lines
|
3109
3182
|
reload_blocks = true
|
@@ -3111,7 +3184,7 @@ module MarkdownExec
|
|
3111
3184
|
|
3112
3185
|
# load document ux block
|
3113
3186
|
#
|
3114
|
-
if code_lines = load_auto_ux_block(all_blocks, mdoc)
|
3187
|
+
if (code_lines = load_auto_ux_block(all_blocks, mdoc))
|
3115
3188
|
new_code = HashDelegator.code_merge(link_state.inherited_lines,
|
3116
3189
|
code_lines)
|
3117
3190
|
next_state_set_code(nil, link_state, new_code)
|
@@ -3121,7 +3194,7 @@ module MarkdownExec
|
|
3121
3194
|
|
3122
3195
|
# load document vars block
|
3123
3196
|
#
|
3124
|
-
if code_lines = load_auto_vars_block(all_blocks)
|
3197
|
+
if (code_lines = load_auto_vars_block(all_blocks))
|
3125
3198
|
new_code = HashDelegator.code_merge(link_state.inherited_lines,
|
3126
3199
|
code_lines)
|
3127
3200
|
next_state_set_code(nil, link_state, new_code)
|
@@ -3153,7 +3226,7 @@ module MarkdownExec
|
|
3153
3226
|
#
|
3154
3227
|
menu_blocks.each do |fcb|
|
3155
3228
|
fcb.body = fcb.raw_body || fcb.body || []
|
3156
|
-
fcb.
|
3229
|
+
fcb.name_in_menu!(fcb.raw_dname || fcb.dname)
|
3157
3230
|
fcb.s0printable = fcb.raw_s0printable || fcb.s0printable
|
3158
3231
|
fcb.s1decorated = fcb.raw_s1decorated || fcb.s1decorated
|
3159
3232
|
expand_references!(fcb, link_state)
|
@@ -3185,7 +3258,7 @@ module MarkdownExec
|
|
3185
3258
|
#
|
3186
3259
|
return unless block.nil?
|
3187
3260
|
|
3188
|
-
chrome_block =
|
3261
|
+
chrome_block = persist_fcb(
|
3189
3262
|
chrome: true,
|
3190
3263
|
disabled: TtyMenu::DISABLE,
|
3191
3264
|
dname: HashDelegator.new(@delegate_object).string_send_color(
|
@@ -3267,7 +3340,10 @@ module MarkdownExec
|
|
3267
3340
|
next_state_set_code(
|
3268
3341
|
selected,
|
3269
3342
|
link_state,
|
3270
|
-
HashDelegator.code_merge(
|
3343
|
+
HashDelegator.code_merge(
|
3344
|
+
link_state&.inherited_lines,
|
3345
|
+
code_lines.is_a?(Array) ? code_lines : [] # no code for :ux_exec_prohibited
|
3346
|
+
)
|
3271
3347
|
)
|
3272
3348
|
end
|
3273
3349
|
|
@@ -3341,6 +3417,12 @@ module MarkdownExec
|
|
3341
3417
|
prompt_select_continue == MenuState::EXIT
|
3342
3418
|
end
|
3343
3419
|
|
3420
|
+
def persist_fcb(options)
|
3421
|
+
MarkdownExec::FCB.new(options).tap do |fcb|
|
3422
|
+
@fcb_store << fcb
|
3423
|
+
end
|
3424
|
+
end
|
3425
|
+
|
3344
3426
|
def pop_add_current_code_to_head_and_trigger_load(
|
3345
3427
|
link_state, block_names, code_lines,
|
3346
3428
|
dependencies, selected, next_block_name: nil
|
@@ -3409,8 +3491,8 @@ module MarkdownExec
|
|
3409
3491
|
#
|
3410
3492
|
# @param all_blocks [Array<Hash>] The list of blocks from the file.
|
3411
3493
|
def select_blocks(menu_blocks)
|
3412
|
-
menu_blocks.
|
3413
|
-
|
3494
|
+
menu_blocks.reject do |fcb|
|
3495
|
+
Filter.prepared_not_in_menu?(
|
3414
3496
|
@delegate_object,
|
3415
3497
|
fcb,
|
3416
3498
|
%i[block_name_include_match block_name_wrapper_match]
|
@@ -3659,16 +3741,16 @@ module MarkdownExec
|
|
3659
3741
|
|
3660
3742
|
case @delegate_object[:publish_document_file_mode]
|
3661
3743
|
when 'append'
|
3662
|
-
File.write(pipe_path, message
|
3744
|
+
File.write(pipe_path, "#{message}\n", mode: 'a')
|
3663
3745
|
when 'fifo'
|
3664
3746
|
unless @vux_pipe_open
|
3665
3747
|
unless File.exist?(pipe_path)
|
3666
|
-
|
3748
|
+
File.mkfifo(pipe_path)
|
3667
3749
|
@vux_pipe_created = pipe_path
|
3668
3750
|
end
|
3669
3751
|
@vux_pipe_open = File.open(pipe_path, 'w')
|
3670
3752
|
end
|
3671
|
-
@vux_pipe_open.puts(message
|
3753
|
+
@vux_pipe_open.puts("#{message}\n")
|
3672
3754
|
@vux_pipe_open.flush
|
3673
3755
|
when 'write'
|
3674
3756
|
File.write(pipe_path, message)
|
@@ -3695,7 +3777,6 @@ module MarkdownExec
|
|
3695
3777
|
regexp: @delegate_object[:saved_asset_match]
|
3696
3778
|
)
|
3697
3779
|
history_files(
|
3698
|
-
@dml_link_state,
|
3699
3780
|
filename:
|
3700
3781
|
if asset.present?
|
3701
3782
|
saved_asset_filename(asset, @dml_link_state)
|
@@ -3710,7 +3791,8 @@ module MarkdownExec
|
|
3710
3791
|
end
|
3711
3792
|
|
3712
3793
|
saved_asset = saved_asset_for_history(
|
3713
|
-
file: file,
|
3794
|
+
file: file,
|
3795
|
+
form: form,
|
3714
3796
|
match_info: $LAST_MATCH_INFO
|
3715
3797
|
)
|
3716
3798
|
saved_asset == :break ? nil : saved_asset
|
@@ -3959,7 +4041,7 @@ module MarkdownExec
|
|
3959
4041
|
|
3960
4042
|
def screen_width
|
3961
4043
|
width = @delegate_object[:screen_width]
|
3962
|
-
if width
|
4044
|
+
if width&.positive?
|
3963
4045
|
width
|
3964
4046
|
else
|
3965
4047
|
@delegate_object[:console_width]
|
@@ -3976,7 +4058,7 @@ module MarkdownExec
|
|
3976
4058
|
end
|
3977
4059
|
|
3978
4060
|
def select_document_if_multiple(options, files, prompt:)
|
3979
|
-
return files if files.
|
4061
|
+
return files if files.instance_of?(String)
|
3980
4062
|
return files[0] if (count = files.count) == 1
|
3981
4063
|
|
3982
4064
|
return unless count >= 2
|
@@ -3994,7 +4076,11 @@ module MarkdownExec
|
|
3994
4076
|
|
3995
4077
|
# Presents a TTY prompt to select an option or exit,
|
3996
4078
|
# returns metadata including option and selected
|
3997
|
-
def select_option_with_metadata(
|
4079
|
+
def select_option_with_metadata(
|
4080
|
+
prompt_text, menu_items, opts = {}, menu_blocks: nil
|
4081
|
+
)
|
4082
|
+
@dml_menu_blocks = menu_blocks if menu_blocks
|
4083
|
+
|
3998
4084
|
## configure to environment
|
3999
4085
|
#
|
4000
4086
|
register_console_attributes(opts)
|
@@ -4039,23 +4125,16 @@ module MarkdownExec
|
|
4039
4125
|
return
|
4040
4126
|
end
|
4041
4127
|
|
4042
|
-
selected =
|
4128
|
+
selected = @dml_menu_blocks.find do |item|
|
4043
4129
|
if item.instance_of?(Hash)
|
4044
4130
|
[item[:id], item[:name], item[:dname]].include?(selection)
|
4045
4131
|
elsif item.instance_of?(MarkdownExec::FCB)
|
4046
|
-
item.
|
4132
|
+
item.id == selection
|
4047
4133
|
else
|
4048
4134
|
item == selection
|
4049
4135
|
end
|
4050
4136
|
end
|
4051
4137
|
|
4052
|
-
# new FCB if selected is not an object
|
4053
|
-
if selected.instance_of?(String)
|
4054
|
-
selected = FCB.new(dname: selected)
|
4055
|
-
elsif selected.instance_of?(Hash)
|
4056
|
-
selected = FCB.new(selected)
|
4057
|
-
end
|
4058
|
-
|
4059
4138
|
unless selected
|
4060
4139
|
HashDelegator.error_handler('select_option_with_metadata',
|
4061
4140
|
error: 'menu item not found')
|
@@ -4168,7 +4247,7 @@ module MarkdownExec
|
|
4168
4247
|
TtyMenu::ENABLE
|
4169
4248
|
end
|
4170
4249
|
|
4171
|
-
|
4250
|
+
persist_fcb(
|
4172
4251
|
body: [],
|
4173
4252
|
call: rest.match(
|
4174
4253
|
Regexp.new(@delegate_object[:block_calls_scan])
|
@@ -4206,6 +4285,21 @@ module MarkdownExec
|
|
4206
4285
|
HashDelegator.apply_color_from_hash(string, @delegate_object, color_sym)
|
4207
4286
|
end
|
4208
4287
|
|
4288
|
+
def transform_export_value(value, export)
|
4289
|
+
return value unless export.transform.present?
|
4290
|
+
|
4291
|
+
if export.transform.is_a? Symbol
|
4292
|
+
value.send(export.transform)
|
4293
|
+
else
|
4294
|
+
format(
|
4295
|
+
export.transform,
|
4296
|
+
NamedCaptureExtractor.extract_named_groups(
|
4297
|
+
value, export.validate
|
4298
|
+
)
|
4299
|
+
)
|
4300
|
+
end
|
4301
|
+
end
|
4302
|
+
|
4209
4303
|
##
|
4210
4304
|
# Processes an individual line within a loop, updating headings
|
4211
4305
|
# and handling fenced code blocks.
|
@@ -4278,7 +4372,9 @@ module MarkdownExec
|
|
4278
4372
|
# add line if it is depth 0 or option allows it
|
4279
4373
|
#
|
4280
4374
|
HashDelegator.yield_line_if_selected(
|
4281
|
-
line, selected_types,
|
4375
|
+
line, selected_types,
|
4376
|
+
all_fcbs: @fcb_store,
|
4377
|
+
source_id: source_id, &block
|
4282
4378
|
)
|
4283
4379
|
end
|
4284
4380
|
end
|
@@ -4317,7 +4413,7 @@ module MarkdownExec
|
|
4317
4413
|
end
|
4318
4414
|
|
4319
4415
|
def vux_execute_and_prompt(block_name)
|
4320
|
-
@dml_block_state =
|
4416
|
+
@dml_block_state = find_block_state_by_name(block_name)
|
4321
4417
|
if @dml_block_state.block &&
|
4322
4418
|
@dml_block_state.block.type == BlockType::OPTS
|
4323
4419
|
debounce_reset
|
@@ -4372,7 +4468,7 @@ module MarkdownExec
|
|
4372
4468
|
|
4373
4469
|
when formatted_choice_ostructs[:history].pub_name
|
4374
4470
|
debounce_reset
|
4375
|
-
return :break unless files_table_rows = vux_history_files_table_rows
|
4471
|
+
return :break unless (files_table_rows = vux_history_files_table_rows)
|
4376
4472
|
|
4377
4473
|
execute_history_select(files_table_rows, stream: $stderr)
|
4378
4474
|
return :break if pause_user_exit
|
@@ -4490,7 +4586,8 @@ module MarkdownExec
|
|
4490
4586
|
|
4491
4587
|
inherited_block_names = []
|
4492
4588
|
inherited_dependencies = {}
|
4493
|
-
selected =
|
4589
|
+
selected = persist_fcb(oname: 'load_code')
|
4590
|
+
|
4494
4591
|
pop_add_current_code_to_head_and_trigger_load(
|
4495
4592
|
@dml_link_state, inherited_block_names,
|
4496
4593
|
code_lines, inherited_dependencies, selected
|
@@ -4498,9 +4595,9 @@ module MarkdownExec
|
|
4498
4595
|
end
|
4499
4596
|
|
4500
4597
|
def vux_load_inherited
|
4501
|
-
return unless filespec = load_filespec_from_expression(
|
4598
|
+
return unless (filespec = load_filespec_from_expression(
|
4502
4599
|
document_name_in_glob_as_file_name
|
4503
|
-
)
|
4600
|
+
))
|
4504
4601
|
|
4505
4602
|
@dml_link_state.inherited_lines_append(
|
4506
4603
|
File.readlines(filespec, chomp: true)
|
@@ -4619,7 +4716,6 @@ module MarkdownExec
|
|
4619
4716
|
)
|
4620
4717
|
if @delegate_object[:menu_for_history]
|
4621
4718
|
history_files(
|
4622
|
-
@dml_link_state,
|
4623
4719
|
filename: saved_asset_filename(@delegate_object[:filename],
|
4624
4720
|
@dml_link_state),
|
4625
4721
|
path: @delegate_object[:saved_script_folder]
|
@@ -4759,7 +4855,7 @@ module MarkdownExec
|
|
4759
4855
|
def vux_user_selected_block_name
|
4760
4856
|
if @dml_link_state.block_name.present?
|
4761
4857
|
# @prior_block_was_link = true
|
4762
|
-
@dml_block_state.block =
|
4858
|
+
@dml_block_state.block = find_block_by_name(
|
4763
4859
|
@dml_blocks_in_file,
|
4764
4860
|
@dml_link_state.block_name
|
4765
4861
|
)
|
@@ -4818,15 +4914,17 @@ module MarkdownExec
|
|
4818
4914
|
menu_blocks.find do |block|
|
4819
4915
|
block.dname.include?(prior_answer)
|
4820
4916
|
end&.name
|
4821
|
-
when Struct
|
4917
|
+
when Struct, MarkdownExec::FCB
|
4822
4918
|
if prior_answer.id
|
4823
|
-
|
4919
|
+
# when switching documents, the prior answer will not be found
|
4920
|
+
(menu_blocks.find_index do |block|
|
4824
4921
|
block[:id] == prior_answer.id
|
4825
|
-
end + 1
|
4922
|
+
end || 0) + 1
|
4826
4923
|
else
|
4827
4924
|
prior_answer.index || prior_answer.name
|
4828
4925
|
end
|
4829
4926
|
end
|
4927
|
+
|
4830
4928
|
# prior_answer value may not match if color is different from
|
4831
4929
|
# originating menu (opts changed while processing)
|
4832
4930
|
selection_opts = if selected_answer
|
@@ -5157,13 +5255,12 @@ module MarkdownExec
|
|
5157
5255
|
|
5158
5256
|
class TestHashDelegatorAppendDivider < Minitest::Test
|
5159
5257
|
def setup
|
5160
|
-
@hd = HashDelegator.new
|
5161
|
-
|
5162
|
-
|
5163
|
-
|
5164
|
-
|
5165
|
-
|
5166
|
-
})
|
5258
|
+
@hd = HashDelegator.new(
|
5259
|
+
menu_divider_color: :color,
|
5260
|
+
menu_divider_format: 'Format',
|
5261
|
+
menu_final_divider: 'Final Divider',
|
5262
|
+
menu_initial_divider: 'Initial Divider'
|
5263
|
+
)
|
5167
5264
|
@hd.stubs(:string_send_color).returns('Formatted Divider')
|
5168
5265
|
HashDelegator.stubs(:safeval).returns('Safe Value')
|
5169
5266
|
end
|
@@ -5185,7 +5282,7 @@ module MarkdownExec
|
|
5185
5282
|
end
|
5186
5283
|
|
5187
5284
|
def test_append_divider_without_format
|
5188
|
-
@hd.
|
5285
|
+
@hd = HashDelegator.new
|
5189
5286
|
menu_blocks = []
|
5190
5287
|
@hd.append_divider(menu_blocks: menu_blocks, position: :initial)
|
5191
5288
|
|
@@ -5223,7 +5320,6 @@ module MarkdownExec
|
|
5223
5320
|
@hd = HashDelegator.new
|
5224
5321
|
@hd.stubs(:iter_blocks_from_nested_files).yields(:blocks, FCB.new)
|
5225
5322
|
@hd.stubs(:create_and_add_chrome_blocks)
|
5226
|
-
@hd.instance_variable_set(:@delegate_object, {})
|
5227
5323
|
HashDelegator.stubs(:error_handler)
|
5228
5324
|
end
|
5229
5325
|
|
@@ -5234,7 +5330,7 @@ module MarkdownExec
|
|
5234
5330
|
end
|
5235
5331
|
|
5236
5332
|
def test_blocks_from_nested_files_with_no_chrome
|
5237
|
-
@hd.
|
5333
|
+
@hd = HashDelegator.new(no_chrome: true)
|
5238
5334
|
@hd.expects(:create_and_add_chrome_blocks).never
|
5239
5335
|
|
5240
5336
|
result = @hd.blocks_from_nested_files
|
@@ -5246,7 +5342,6 @@ module MarkdownExec
|
|
5246
5342
|
class TestHashDelegatorCollectRequiredCodeLines < Minitest::Test
|
5247
5343
|
def setup
|
5248
5344
|
@hd = HashDelegator.new
|
5249
|
-
@hd.instance_variable_set(:@delegate_object, {})
|
5250
5345
|
@mdoc = mock('YourMDocClass')
|
5251
5346
|
@selected = FCB.new(
|
5252
5347
|
body: ['key: value'],
|
@@ -5272,15 +5367,13 @@ module MarkdownExec
|
|
5272
5367
|
class TestHashDelegatorCommandOrUserSelectedBlock < Minitest::Test
|
5273
5368
|
def setup
|
5274
5369
|
@hd = HashDelegator.new
|
5275
|
-
@hd.instance_variable_set(:@delegate_object, {})
|
5276
5370
|
HashDelegator.stubs(:error_handler)
|
5277
5371
|
@hd.stubs(:wait_for_user_selected_block)
|
5278
5372
|
end
|
5279
5373
|
|
5280
5374
|
def test_command_selected_block
|
5281
5375
|
all_blocks = [{ oname: 'block1' }, { oname: 'block2' }]
|
5282
|
-
@hd.
|
5283
|
-
{ block_name: 'block1' })
|
5376
|
+
@hd = HashDelegator.new(block_name: 'block1')
|
5284
5377
|
|
5285
5378
|
result = @hd.load_cli_or_user_selected_block(all_blocks: all_blocks)
|
5286
5379
|
|
@@ -5309,10 +5402,10 @@ module MarkdownExec
|
|
5309
5402
|
|
5310
5403
|
class TestHashDelegatorCountBlockInFilename < Minitest::Test
|
5311
5404
|
def setup
|
5312
|
-
@hd = HashDelegator.new
|
5313
|
-
|
5314
|
-
|
5315
|
-
|
5405
|
+
@hd = HashDelegator.new(
|
5406
|
+
fenced_start_and_end_regex: '^```',
|
5407
|
+
filename: '/path/to/file'
|
5408
|
+
)
|
5316
5409
|
@hd.stubs(:cfile).returns(mock('cfile'))
|
5317
5410
|
end
|
5318
5411
|
|
@@ -5421,7 +5514,6 @@ module MarkdownExec
|
|
5421
5514
|
def setup
|
5422
5515
|
@hd = HashDelegator.new
|
5423
5516
|
@hd.instance_variable_set(:@fout, mock('fout'))
|
5424
|
-
@hd.instance_variable_set(:@delegate_object, {})
|
5425
5517
|
@hd.stubs(:string_send_color)
|
5426
5518
|
end
|
5427
5519
|
|
@@ -5443,7 +5535,6 @@ module MarkdownExec
|
|
5443
5535
|
class TestHashDelegatorFetchColor < Minitest::Test
|
5444
5536
|
def setup
|
5445
5537
|
@hd = HashDelegator.new
|
5446
|
-
@hd.instance_variable_set(:@delegate_object, {})
|
5447
5538
|
end
|
5448
5539
|
|
5449
5540
|
def test_fetch_color_with_valid_data
|
@@ -5476,7 +5567,6 @@ module MarkdownExec
|
|
5476
5567
|
class TestHashDelegatorFormatReferencesSendColor < Minitest::Test
|
5477
5568
|
def setup
|
5478
5569
|
@hd = HashDelegator.new
|
5479
|
-
@hd.instance_variable_set(:@delegate_object, {})
|
5480
5570
|
end
|
5481
5571
|
|
5482
5572
|
def test_format_references_send_color_with_valid_data
|
@@ -5581,7 +5671,6 @@ module MarkdownExec
|
|
5581
5671
|
# )
|
5582
5672
|
|
5583
5673
|
# def history_files(
|
5584
|
-
# link_state,
|
5585
5674
|
# direction: :reverse,
|
5586
5675
|
# filename: nil,
|
5587
5676
|
# home: Dir.pwd,
|
@@ -5590,9 +5679,10 @@ module MarkdownExec
|
|
5590
5679
|
# )
|
5591
5680
|
|
5592
5681
|
def test_call
|
5593
|
-
@hd.expects(:history_files).with(
|
5594
|
-
@hd.execute_block_type_history_ux(
|
5595
|
-
|
5682
|
+
@hd.expects(:history_files).with(filename: '*', path: nil).once
|
5683
|
+
@hd.execute_block_type_history_ux(
|
5684
|
+
filename: '*', link_state: LinkState.new, selected: FCB.new(body: [])
|
5685
|
+
)
|
5596
5686
|
end
|
5597
5687
|
end
|
5598
5688
|
|
@@ -5677,11 +5767,9 @@ module MarkdownExec
|
|
5677
5767
|
|
5678
5768
|
class TestHashDelegatorHandleStream < Minitest::Test
|
5679
5769
|
def setup
|
5680
|
-
@hd = HashDelegator.new
|
5770
|
+
@hd = HashDelegator.new(output_stdout: true)
|
5681
5771
|
@hd.instance_variable_set(:@run_state,
|
5682
5772
|
OpenStruct.new(files: StreamsOut.new))
|
5683
|
-
@hd.instance_variable_set(:@delegate_object,
|
5684
|
-
{ output_stdout: true })
|
5685
5773
|
end
|
5686
5774
|
|
5687
5775
|
def test_handle_stream
|
@@ -5691,7 +5779,7 @@ module MarkdownExec
|
|
5691
5779
|
Thread.new { @hd.handle_stream(stream: stream, file_type: file_type) }
|
5692
5780
|
|
5693
5781
|
@hd.wait_for_stream_processing
|
5694
|
-
assert_equal [
|
5782
|
+
assert_equal ["line 1\n", "line 2\n"],
|
5695
5783
|
@hd.instance_variable_get(:@run_state)
|
5696
5784
|
.files.stream_lines(ExecutionStreams::STD_OUT)
|
5697
5785
|
end
|
@@ -5713,9 +5801,7 @@ module MarkdownExec
|
|
5713
5801
|
|
5714
5802
|
class TestHashDelegatorIterBlocksFromNestedFiles < Minitest::Test
|
5715
5803
|
def setup
|
5716
|
-
@hd = HashDelegator.new
|
5717
|
-
@hd.instance_variable_set(:@delegate_object,
|
5718
|
-
{ filename: 'test.md' })
|
5804
|
+
@hd = HashDelegator.new(filename: 'test.md')
|
5719
5805
|
@hd.stubs(:check_file_existence).with('test.md').returns(true)
|
5720
5806
|
@hd.stubs(:initial_state).returns({})
|
5721
5807
|
@hd.stubs(:cfile).returns(Minitest::Mock.new)
|
@@ -5744,12 +5830,11 @@ module MarkdownExec
|
|
5744
5830
|
|
5745
5831
|
class TestHashDelegatorMenuChromeColoredOption < Minitest::Test
|
5746
5832
|
def setup
|
5747
|
-
@hd = HashDelegator.new
|
5748
|
-
|
5749
|
-
|
5750
|
-
|
5751
|
-
|
5752
|
-
})
|
5833
|
+
@hd = HashDelegator.new(
|
5834
|
+
menu_chrome_color: :red,
|
5835
|
+
menu_chrome_format: '-- %s --',
|
5836
|
+
menu_option_back_name: 'Back'
|
5837
|
+
)
|
5753
5838
|
@hd.stubs(:menu_chrome_formatted_option)
|
5754
5839
|
.with(:menu_option_back_name).returns('-- Back --')
|
5755
5840
|
@hd.stubs(:string_send_color)
|
@@ -5763,8 +5848,9 @@ module MarkdownExec
|
|
5763
5848
|
end
|
5764
5849
|
|
5765
5850
|
def test_menu_chrome_colored_option_without_color
|
5766
|
-
@hd.
|
5767
|
-
|
5851
|
+
@hd = HashDelegator.new(menu_option_back_name: 'Back')
|
5852
|
+
@hd.stubs(:menu_chrome_formatted_option)
|
5853
|
+
.with(:menu_option_back_name).returns('-- Back --')
|
5768
5854
|
assert_equal '-- Back --',
|
5769
5855
|
@hd.menu_chrome_colored_option(:menu_option_back_name)
|
5770
5856
|
end
|
@@ -5772,11 +5858,10 @@ module MarkdownExec
|
|
5772
5858
|
|
5773
5859
|
class TestHashDelegatorMenuChromeOption < Minitest::Test
|
5774
5860
|
def setup
|
5775
|
-
@hd = HashDelegator.new
|
5776
|
-
|
5777
|
-
|
5778
|
-
|
5779
|
-
})
|
5861
|
+
@hd = HashDelegator.new(
|
5862
|
+
menu_chrome_format: '-- %s --',
|
5863
|
+
menu_option_back_name: "'Back'"
|
5864
|
+
)
|
5780
5865
|
HashDelegator.stubs(:safeval).with("'Back'").returns('Back')
|
5781
5866
|
end
|
5782
5867
|
|
@@ -5786,8 +5871,7 @@ module MarkdownExec
|
|
5786
5871
|
end
|
5787
5872
|
|
5788
5873
|
def test_menu_chrome_formatted_option_without_format
|
5789
|
-
@hd.
|
5790
|
-
{ menu_option_back_name: "'Back'" })
|
5874
|
+
@hd = HashDelegator.new(menu_option_back_name: "'Back'")
|
5791
5875
|
assert_equal 'Back',
|
5792
5876
|
@hd.menu_chrome_formatted_option(:menu_option_back_name)
|
5793
5877
|
end
|
@@ -5795,10 +5879,12 @@ module MarkdownExec
|
|
5795
5879
|
|
5796
5880
|
class TestHashDelegatorStartFencedBlock < Minitest::Test
|
5797
5881
|
def setup
|
5798
|
-
@hd = HashDelegator.new(
|
5799
|
-
|
5800
|
-
|
5801
|
-
|
5882
|
+
@hd = HashDelegator.new(
|
5883
|
+
{
|
5884
|
+
block_calls_scan: 'CALLS_REGEX',
|
5885
|
+
block_name_wrapper_match: 'WRAPPER_REGEX'
|
5886
|
+
}
|
5887
|
+
)
|
5802
5888
|
end
|
5803
5889
|
|
5804
5890
|
def test_start_fenced_block
|
@@ -5816,9 +5902,7 @@ module MarkdownExec
|
|
5816
5902
|
|
5817
5903
|
class TestHashDelegatorStringSendColor < Minitest::Test
|
5818
5904
|
def setup
|
5819
|
-
@hd = HashDelegator.new
|
5820
|
-
@hd.instance_variable_set(:@delegate_object,
|
5821
|
-
{ red: 'red', green: 'green' })
|
5905
|
+
@hd = HashDelegator.new(red: 'red', green: 'green')
|
5822
5906
|
end
|
5823
5907
|
|
5824
5908
|
def test_string_send_color
|