markdown_exec 2.7.5 → 2.8.1
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 +28 -0
- data/Gemfile.lock +1 -1
- data/Rakefile +22 -1
- data/bats/block-type-ux-auto.bats +8 -0
- data/bats/block-type-ux-exec.bats +8 -0
- data/bats/block-type-ux-row-format.bats +8 -0
- data/bats/block-type-ux-transform.bats +8 -0
- data/bats/command-substitution.bats +1 -1
- data/bats/line-wrapping.bats +1 -1
- data/bats/table-column-truncate.bats +8 -0
- data/bats/table.bats +1 -1
- data/bin/tab_completion.sh +1 -1
- data/docs/dev/bats-document-configuration.md +3 -0
- data/docs/dev/block-type-ux-auto.md +43 -0
- data/docs/dev/block-type-ux-exec.md +42 -0
- data/docs/dev/block-type-ux-row-format.md +47 -0
- data/docs/dev/block-type-ux-transform.md +41 -0
- data/docs/dev/command-substitution.md +1 -0
- data/docs/dev/table-column-truncate.md +17 -0
- data/docs/dev/table-indent.md +1 -0
- data/examples/colors.md +2 -0
- data/lib/block_types.rb +1 -0
- data/lib/constants.rb +4 -2
- data/lib/evaluate_shell_expressions.rb +29 -24
- data/lib/fcb.rb +47 -37
- data/lib/format_table.rb +8 -7
- data/lib/hash_delegator.rb +332 -69
- data/lib/hierarchy_string.rb +3 -2
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +5 -8
- data/lib/mdoc.rb +52 -21
- data/lib/menu.src.yml +30 -0
- data/lib/menu.yml +27 -0
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d752af0db5e1c1a770b64f9341c3d08e1e9bc8612230a9cb44ddc7fddc4c3051
|
4
|
+
data.tar.gz: 5ba8524b3323bd8333b82a5d0607fbb9db59a5157a1c7ae0564b3f624f26addd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29b210e56b46a1edf099c02267e2b3c7cdae6701f7ee99d5a946d06eea7272da3534765110ec36a6de017a10d0f4833c9075c27dacb0cec8b050192d3892d748
|
7
|
+
data.tar.gz: e73cd906ce9035c8c78d2e301866af4a76bc7a730c5109fc8cc59ecf64679cb578fb04b324e700df064886d250c394c441f77850b9e21230d346d08bd92a9a5f
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [2.8.0] - 2025-02-10
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- Block type `ux` to facilitate the evaluation, display, and editing of shell variables.
|
8
|
+
The body of the `ux` block is in YAML.
|
9
|
+
|
10
|
+
A valid shell variable name is required as block key `name`. The remaining block keys are optional.
|
11
|
+
|
12
|
+
When the block is executed, its value is computed from the `default`, `exec`, `prompt`, `transform`, and `validate` keys and its output is assigned to the shell variable.
|
13
|
+
|
14
|
+
When a document is loaded, if one or more block names match `document_load_ux_block_name`, they are executed.
|
15
|
+
`ux_auto_load_force_default` limits the setting of the shell variable resulting from the execution of blocks executed at this time.
|
16
|
+
|
17
|
+
When an `ux` block is executed (after initial document load):
|
18
|
+
If the `default` value is the `exec` symbol, the command in the `exec` key is executed and its output is processed.
|
19
|
+
Else if the `allowed` value has one or more items, the user must pick from one of the items.
|
20
|
+
Else if the `prompt` value exists, the user must enter a value or nothing for the `default` value. The user is prompted with `prompt_ux_enter_a_value`.
|
21
|
+
Else the `default` value, as a string, is processed.
|
22
|
+
|
23
|
+
The output is validated/parsed by the regular expression in `validate`.
|
24
|
+
If the string matches, named groups are formatted with `menu_ux_row_format` and assigned to the shell variable.
|
25
|
+
|
26
|
+
The default `menu_ux_row_format` looks like a shell variable assignment.
|
27
|
+
If the output of `menu_ux_row_format` matches an immediately preceding table, the row is merged into that table.
|
28
|
+
Else the output is decorated with `menu_ux_color`.
|
29
|
+
- Improve final output of `test` Rake task so failures are visible.
|
30
|
+
|
3
31
|
## [2.7.5] - 2025-02-02
|
4
32
|
|
5
33
|
### Added
|
data/Gemfile.lock
CHANGED
data/Rakefile
CHANGED
@@ -155,9 +155,30 @@ end
|
|
155
155
|
|
156
156
|
desc 'test'
|
157
157
|
task :test do
|
158
|
-
|
158
|
+
success = true
|
159
|
+
|
160
|
+
# Run all tests and track failures
|
161
|
+
rspec_success = system('bundle exec rspec')
|
162
|
+
success = false unless rspec_success
|
163
|
+
|
159
164
|
Rake::Task['minitest'].invoke
|
165
|
+
minitest_success = $?.success?
|
166
|
+
success = false unless minitest_success
|
167
|
+
|
160
168
|
Rake::Task['bats'].invoke
|
169
|
+
bats_success = $?.success?
|
170
|
+
success = false unless bats_success
|
171
|
+
|
172
|
+
# Report failures and exit with non-zero status if any test failed
|
173
|
+
unless success
|
174
|
+
failed_tests = []
|
175
|
+
failed_tests << 'RSpec' unless rspec_success
|
176
|
+
failed_tests << 'Minitest' unless minitest_success
|
177
|
+
failed_tests << 'Bats' unless bats_success
|
178
|
+
|
179
|
+
puts "\nThe following test suites failed: #{failed_tests.join(', ')}"
|
180
|
+
exit 1
|
181
|
+
end
|
161
182
|
end
|
162
183
|
|
163
184
|
private
|
@@ -0,0 +1,8 @@
|
|
1
|
+
#!/usr/bin/env bats
|
2
|
+
|
3
|
+
load 'test_helper'
|
4
|
+
|
5
|
+
@test 'Row format merges with prior table' {
|
6
|
+
spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-type-ux-row-format.md \
|
7
|
+
' | Variable | Value | Prompt |_ | --------- | ---------------- | ------------------- |_ | Species | Pongo tapanulien | New species? |_ | Name: Gen | Value: Pongo | Prompt: New genus? |_ | Family | Hominidae | Enter a value: |'
|
8
|
+
}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
#!/usr/bin/env bats
|
2
|
+
|
3
|
+
load 'test_helper'
|
4
|
+
|
5
|
+
@test 'Transformed output of executed commands' {
|
6
|
+
spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-type-ux-transform.md \
|
7
|
+
'_Execution output has a trailing newline._Var0=markdown_exec_00000000 6d 61 72 6b 64 6f 77 6e 5f 65 78 65 63 0a |markdown_exec.|__With validate and transform, output has no newline._Var1=markdown_exec_00000000 6d 61 72 6b 64 6f 77 6e 5f 65 78 65 63 |markdown_exec|__With transform :chomp, output has no newline._Var2=markdown_exec_00000000 6d 61 72 6b 64 6f 77 6e 5f 65 78 65 63 |markdown_exec|__With transform :upcase, output is in upper case w/ newline._Var3=MARKDOWN_EXEC_00000000 4d 41 52 4b 44 4f 57 4e 5f 45 58 45 43 0a |MARKDOWN_EXEC.|'
|
8
|
+
}
|
@@ -4,5 +4,5 @@ load 'test_helper'
|
|
4
4
|
|
5
5
|
@test 'Command substitution' {
|
6
6
|
spec_mde_xansi_dname_doc_blocks_expect docs/dev/command-substitution.md \
|
7
|
-
'CURRENT BASE NAME IS: MARKDOWN_EXEC_current base name is: markdown_exec_current base name is: markdown_exec_| current base name |_| ----------------- |_| markdown_exec |_: notice the string is not expanded in Shell block types (names or body)._ echo "current base name is now $(basename `pwd`)"__load: file_markdown_exec.
|
7
|
+
'CURRENT BASE NAME IS: MARKDOWN_EXEC_current base name is: markdown_exec_current base name is: markdown_exec_| current base name |_| ----------------- |_| markdown_exec |_: notice the string is not expanded in Shell block types (names or body)._ echo "current base name is now $(basename `pwd`)"__load: file_markdown_exec.sh_Status not zero: $(err)'
|
8
8
|
}
|
data/bats/line-wrapping.bats
CHANGED
@@ -4,5 +4,5 @@ load 'test_helper'
|
|
4
4
|
|
5
5
|
@test 'Text and Headings' {
|
6
6
|
spec_mde_xansi_dname_doc_blocks_expect docs/dev/line-wrapping.md \
|
7
|
-
"
|
7
|
+
" DEMO WRAPPING LONG LINES__MDE detects the screen's dimensions:_height (lines) and width (characters)__Normal document text is displayed as_disabled menu lines. The width of these_lines is limited according to the_screen's width.__Test Indented Lines__ Indented with two spaces, this line_ should wrap in an aesthetically_ pleasing way.__ Indented with a tab, this line should_ wrap in an aesthetically pleasing_ way.__ SPECIES GENUS FAMILY ORDER CLASS PHYLUM_ KINGDOM DOMAIN_species genus family order class phylum_kingdom domain"
|
8
8
|
}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
#!/usr/bin/env bats
|
2
|
+
|
3
|
+
load 'test_helper'
|
4
|
+
|
5
|
+
@test 'Tables - truncate columns' {
|
6
|
+
spec_mde_xansi_dname_doc_blocks_expect docs/dev/table-column-truncate.md \
|
7
|
+
'DEMONSTRATE TRUNCATION OF TEXT IN TABLE CELLS__| Common Name | Species | Genus | Family | Year Di |_| ------------ | ------------ | ----- | ------- | ------- |_| Tapanuli Ora | Pongo tapanu | Pongo | Hominid | 2017 |_| Psychedelic | Histiophryne | Histi | Antenna | 2009 |_| Ruby Seadrag | Phyllopteryx | Phyll | Syngnat | 2015 |_| Illacme tobi | Illacme tobi | Illac | Siphono | 2016 |_| Spiny Dandel | Taraxacum ja | Tarax | Asterac | 2022 |__'
|
8
|
+
}
|
data/bats/table.bats
CHANGED
@@ -4,7 +4,7 @@ load 'test_helper'
|
|
4
4
|
|
5
5
|
@test 'Tables - indented' {
|
6
6
|
spec_mde_xansi_dname_doc_blocks_expect docs/dev/table-indent.md \
|
7
|
-
'DEMONSTRATE TABLE INDENTATION__Table flush at left._Centered columns._|
|
7
|
+
'DEMONSTRATE TABLE INDENTATION__Table flush at left._Centered columns._| Common Name | Species | Genus | Family | Year Discover |_| ------------------ | ---------------------- | ---------- | ----------- | ------------- |_| Tapanuli Orangutan | Pongo tapanuliensis | Pongo | Hominidae | 2017 |_| Psychedelic Frogfi | Histiophryne psychedel | Histiophry | Antennariid | 2009 |_| Ruby Seadragon | Phyllopteryx dewysea | Phyllopter | Syngnathida | 2015 |__ Table indented with two spaces._ Left-justified columns._ | Common Name | Species | Genus | Family | Year Discovere |_ | ------------------------- | ------------- | ------ | -------------- | -------------- |_ | Illacme tobini (Millipede | Illacme tobin | Illacm | Siphonorhinida | 2016 |__ Table indented with one tab._ Right-justified columns._ | Common Name | Species | Genus | Family | Year Discovered |_ | --------------- | ------------------- | --------- | ---------- | --------------- |_ | Spiny Dandelion | Taraxacum japonicum | Taraxacum | Asteraceae | 2022 |'
|
8
8
|
}
|
9
9
|
|
10
10
|
@test 'Tables - invalid' {
|
data/bin/tab_completion.sh
CHANGED
@@ -0,0 +1,43 @@
|
|
1
|
+
/ v2025-02-08
|
2
|
+
/ name only
|
3
|
+
```ux
|
4
|
+
name: v1
|
5
|
+
```
|
6
|
+
/ name and default
|
7
|
+
/ transform and validate options not applied to default
|
8
|
+
```ux
|
9
|
+
default: 11
|
10
|
+
name: v2
|
11
|
+
```
|
12
|
+
/ name and default; auto-load
|
13
|
+
/ prompt option is ignored during auto-load
|
14
|
+
```ux :[document_ux_v3]
|
15
|
+
default: 12
|
16
|
+
name: v3
|
17
|
+
```
|
18
|
+
/ name, default, exec; auto-load static
|
19
|
+
```ux :[document_ux_v4]
|
20
|
+
default: 21
|
21
|
+
exec: basename $(pwd)
|
22
|
+
name: v4
|
23
|
+
```
|
24
|
+
/ name, default, exec; auto-load executed `basename $(pwd)`
|
25
|
+
/ allowed is ignored by exec
|
26
|
+
```ux :[document_ux_v5]
|
27
|
+
default: :exec
|
28
|
+
exec: basename $(pwd)
|
29
|
+
name: v5
|
30
|
+
```
|
31
|
+
/ name, default, allowed; auto-load static default
|
32
|
+
```ux :[document_ux_v6]
|
33
|
+
allowed:
|
34
|
+
- 32
|
35
|
+
- 33
|
36
|
+
default: 31
|
37
|
+
name: v6
|
38
|
+
```
|
39
|
+
@import bats-document-configuration.md
|
40
|
+
```opts :(document_opts)
|
41
|
+
menu_ux_row_format: '%{name} = ${%{name}}'
|
42
|
+
ux_auto_load_force_default: true
|
43
|
+
```
|
@@ -0,0 +1,42 @@
|
|
1
|
+
/ auto-load block, does not execute command to calculate
|
2
|
+
/ click block to calculate
|
3
|
+
```ux :[document_ux0]
|
4
|
+
exec: basename $(pwd)
|
5
|
+
name: ux0
|
6
|
+
```
|
7
|
+
/ auto-load block and execute command to calculate
|
8
|
+
/ click block to recalculate
|
9
|
+
```ux :[document_ux1]
|
10
|
+
default: Unknown
|
11
|
+
exec: basename $(pwd)
|
12
|
+
name: ux1
|
13
|
+
```
|
14
|
+
/ auto-load block and execute command to calculate
|
15
|
+
/ click block to recalculate
|
16
|
+
```ux :[document_ux2]
|
17
|
+
default: :exec
|
18
|
+
exec: basename $(pwd)
|
19
|
+
name: ux2
|
20
|
+
```
|
21
|
+
/ required block defining a function used in exec
|
22
|
+
```bash :(bash3)
|
23
|
+
# function from bash3
|
24
|
+
val () { basename $(pwd) ; }
|
25
|
+
```
|
26
|
+
```ux :[document_ux3] +(bash3)
|
27
|
+
default: :exec
|
28
|
+
exec: val
|
29
|
+
name: ux3
|
30
|
+
```
|
31
|
+
/ default is computed
|
32
|
+
/ output of execution is validated/parsed
|
33
|
+
/ parsing is transformed
|
34
|
+
```ux :[document_ux4]
|
35
|
+
default: :exec
|
36
|
+
exec: basename $(pwd)
|
37
|
+
name: ux4
|
38
|
+
transform: "Xform: '%{name}'"
|
39
|
+
validate: |
|
40
|
+
^(?<name>.*)(_.*)$
|
41
|
+
```
|
42
|
+
@import bats-document-configuration.md
|
@@ -0,0 +1,47 @@
|
|
1
|
+
/ v2025-02-08
|
2
|
+
| Variable| Value| Prompt
|
3
|
+
| -| -| -
|
4
|
+
/ auto-load default value
|
5
|
+
/ custom prompt
|
6
|
+
/ select list
|
7
|
+
/ default value
|
8
|
+
```ux :[document_ux_Species]
|
9
|
+
allowed:
|
10
|
+
- Pongo tapanuliensis
|
11
|
+
- Histiophryne psychedelica
|
12
|
+
- Phyllopteryx dewysea
|
13
|
+
default: Pongo tapanuliensis
|
14
|
+
name: Species
|
15
|
+
prompt: New species?
|
16
|
+
```
|
17
|
+
/ auto-load default value
|
18
|
+
/ cell text is prefixed Name/Value/Prompt
|
19
|
+
/ select list contains additional text
|
20
|
+
/ selected value is validated with named groups
|
21
|
+
/ selected value is transformed; named capture is prefixed Xform
|
22
|
+
```ux :[document_ux_Genus]
|
23
|
+
allowed:
|
24
|
+
- 1. Pongo
|
25
|
+
- 2. Histiophryne
|
26
|
+
- 3. Phyllopteryx
|
27
|
+
default: Pongo
|
28
|
+
menu_format: "| Name: %{name}| Value: ${%{name}}| Prompt: %{prompt}"
|
29
|
+
name: Genus
|
30
|
+
prompt: New genus?
|
31
|
+
transform: "Xform: '%{name}'"
|
32
|
+
validate: |
|
33
|
+
^\d+\. *(?<name>[^ ].*)$
|
34
|
+
```
|
35
|
+
/ default
|
36
|
+
/ auto-load default value
|
37
|
+
```ux :[document_ux_Family]
|
38
|
+
default: Hominidae
|
39
|
+
name: Family
|
40
|
+
```
|
41
|
+
@import bats-document-configuration.md
|
42
|
+
```opts :(document_opts)
|
43
|
+
menu_ux_row_format: '| %{name}| ${%{name}}| %{prompt}'
|
44
|
+
screen_width: 64
|
45
|
+
table_center: true
|
46
|
+
ux_auto_load_force_default: true
|
47
|
+
```
|
@@ -0,0 +1,41 @@
|
|
1
|
+
:::
|
2
|
+
**Execution output has a trailing newline.**
|
3
|
+
```ux :[document_ux_transform_0]
|
4
|
+
default: :exec
|
5
|
+
exec: basename $(pwd)
|
6
|
+
name: Var0
|
7
|
+
```
|
8
|
+
$(echo -n "$Var0" | hexdump -C)
|
9
|
+
:::
|
10
|
+
**With validate and transform, output has no newline.**
|
11
|
+
```ux :[document_ux_transform_1]
|
12
|
+
default: :exec
|
13
|
+
exec: basename $(pwd)
|
14
|
+
name: Var1
|
15
|
+
transform: '%{name}'
|
16
|
+
validate: (?<name>.+)
|
17
|
+
```
|
18
|
+
$(echo -n "$Var1" | hexdump -C)
|
19
|
+
:::
|
20
|
+
**With transform `:chomp`, output has no newline.**
|
21
|
+
```ux :[document_ux_transform_2]
|
22
|
+
default: :exec
|
23
|
+
exec: basename $(pwd)
|
24
|
+
name: Var2
|
25
|
+
transform: :chomp
|
26
|
+
```
|
27
|
+
$(echo -n "$Var2" | hexdump -C)
|
28
|
+
:::
|
29
|
+
**With transform `:upcase`, output is in upper case w/ newline.**
|
30
|
+
```ux :[document_ux_transform_3]
|
31
|
+
default: :exec
|
32
|
+
exec: basename $(pwd)
|
33
|
+
name: Var3
|
34
|
+
transform: :upcase
|
35
|
+
```
|
36
|
+
$(echo -n "$Var3" | hexdump -C)
|
37
|
+
@import bats-document-configuration.md
|
38
|
+
```opts :(document_opts)
|
39
|
+
divider4_collapsible: false
|
40
|
+
table_center: false
|
41
|
+
```
|
@@ -11,6 +11,7 @@ echo "current base name is now $(basename `pwd`)"
|
|
11
11
|
```link
|
12
12
|
load: file_$(basename `pwd`).sh
|
13
13
|
```
|
14
|
+
Status not zero: $(err)
|
14
15
|
/ This should not be evaluated $(err). It errs with "Error: HashDelegator.blocks_from_nested_files -- Shell script execution failed: /bin/bash: line 2: err: command not found"
|
15
16
|
@import bats-document-configuration.md
|
16
17
|
```opts :(document_opts)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Demonstrate Truncation of Text in Table Cells
|
2
|
+
|
3
|
+
| Common Name| Species| Genus| Family| Year Discovered
|
4
|
+
| -| -|:-|-:|:-:
|
5
|
+
| Tapanuli Orangutan| Pongo tapanuliensis| Pongo| Hominidae| 2017
|
6
|
+
| Psychedelic Frogfish| Histiophryne psychedelica| Histiophryne| Antennariidae| 2009
|
7
|
+
| Ruby Seadragon| Phyllopteryx dewysea| Phyllopteryx| Syngnathidae| 2015
|
8
|
+
| Illacme tobini (Millipede)| Illacme tobini| Illacme| Siphonorhinidae| 2016
|
9
|
+
| Spiny Dandelion| Taraxacum japonicum| Taraxacum| Asteraceae| 2022
|
10
|
+
```
|
11
|
+
```
|
12
|
+
@import bats-document-configuration.md
|
13
|
+
```opts :(document_opts)
|
14
|
+
heading1_center: false
|
15
|
+
screen_width: 60
|
16
|
+
table_center: false
|
17
|
+
```
|
data/docs/dev/table-indent.md
CHANGED
data/examples/colors.md
CHANGED
@@ -33,6 +33,7 @@ menu_opts_color: fg_rgbh_1f_00_1f
|
|
33
33
|
menu_opts_set_color: fg_rgbh_7f_00_1f
|
34
34
|
menu_save_color: fg_rgbh_e0_e0_20
|
35
35
|
menu_task_color: fg_rgbh_1f_1f_1f
|
36
|
+
menu_ux_color: fg_rgbh_2f_c0_2f
|
36
37
|
menu_vars_color: fg_rgbh_1f_a0_1f
|
37
38
|
menu_vars_set_color: fg_rgbh_00_1f_1f
|
38
39
|
output_execution_label_name_color: fg_rgbh_00_1f_00
|
@@ -60,6 +61,7 @@ menu_opts_set_color: fg_rgbh_7f_00_ff
|
|
60
61
|
# menu_save_color: fg_rgbh_ea_ea_20
|
61
62
|
menu_save_color: fg_rgbh_ff_ff_20
|
62
63
|
menu_task_color: fg_rgbh_ff_ff_ff
|
64
|
+
menu_ux_color: fg_rgbh_df_c0_df
|
63
65
|
menu_vars_color: fg_rgbh_ff_a0_ff
|
64
66
|
menu_vars_set_color: fg_rgbh_00_ff_ff
|
65
67
|
output_execution_label_name_color: fg_rgbh_00_ff_00
|
data/lib/block_types.rb
CHANGED
data/lib/constants.rb
CHANGED
@@ -27,12 +27,12 @@ BLOCK_TYPE_COLOR_OPTIONS = {
|
|
27
27
|
BlockType::OPTS => :menu_opts_color,
|
28
28
|
BlockType::SAVE => :menu_save_color,
|
29
29
|
BlockType::SHELL => :menu_bash_color,
|
30
|
+
BlockType::UX => :menu_ux_color,
|
30
31
|
BlockType::VARS => :menu_vars_color
|
31
32
|
}.freeze
|
32
33
|
|
33
|
-
|
34
34
|
COLLAPSIBLE_SYMBOL_COLLAPSED = '⬢' # '<+>' # '∆'
|
35
|
-
COLLAPSIBLE_SYMBOL_EXPANDED = '⬡' # '< >' # '…'
|
35
|
+
COLLAPSIBLE_SYMBOL_EXPANDED = '⬡' # '< >' # '…'
|
36
36
|
|
37
37
|
# in regexp (?<collapse>[+-~]?)
|
38
38
|
COLLAPSIBLE_TOKEN_COLLAPSE = '+'
|
@@ -100,8 +100,10 @@ end
|
|
100
100
|
|
101
101
|
# selected block and subsequent menu state
|
102
102
|
#
|
103
|
+
BlockSelection = Struct.new(:id)
|
103
104
|
SelectedBlockMenuState = Struct.new(:block, :source, :state)
|
104
105
|
|
105
106
|
class TtyMenu
|
107
|
+
ENABLE = nil
|
106
108
|
DISABLE = ''
|
107
109
|
end
|
@@ -5,8 +5,12 @@
|
|
5
5
|
|
6
6
|
require 'open3'
|
7
7
|
|
8
|
+
class EvaluateShellExpression
|
9
|
+
StatusFail = :script_execution_failed unless const_defined?(:StatusFail)
|
10
|
+
end
|
11
|
+
|
8
12
|
def evaluate_shell_expressions(initial_code, expressions, shell: '/bin/bash',
|
9
|
-
key_format:
|
13
|
+
key_format: '%%<%s>',
|
10
14
|
initial_code_required: false)
|
11
15
|
# !!p initial_code expressions key_format shell
|
12
16
|
return if (initial_code_required && (initial_code.nil? || initial_code.empty?)) ||
|
@@ -18,23 +22,26 @@ def evaluate_shell_expressions(initial_code, expressions, shell: '/bin/bash',
|
|
18
22
|
|
19
23
|
# Construct a single shell script
|
20
24
|
script = initial_code.dup
|
21
|
-
expressions.each_with_index do |(
|
25
|
+
expressions.each_with_index do |(_key, expression), index|
|
22
26
|
script << "\necho #{token}#{index}\n"
|
23
27
|
script << expression << "\n"
|
24
28
|
end
|
25
29
|
|
26
30
|
# Execute
|
27
|
-
stdout_str, stderr_str, status = Open3.capture3(shell,
|
31
|
+
stdout_str, stderr_str, status = Open3.capture3(shell, '-c', script)
|
28
32
|
|
29
33
|
unless status.success?
|
30
|
-
|
34
|
+
return EvaluateShellExpression::StatusFail
|
31
35
|
end
|
32
36
|
|
33
37
|
# Extract output for expressions
|
34
38
|
result_hash = {}
|
35
|
-
stdout_str.split(/\n?#{token}\d+\n/)
|
36
|
-
|
37
|
-
|
39
|
+
part = stdout_str.split(/\n?#{token}\d+\n/)
|
40
|
+
unless part.empty?
|
41
|
+
part[1..-1].tap do |output_parts|
|
42
|
+
expressions.each_with_index do |(key, _expression), index|
|
43
|
+
result_hash[format(key_format, key)] = output_parts[index].chomp
|
44
|
+
end
|
38
45
|
end
|
39
46
|
end
|
40
47
|
|
@@ -58,23 +65,23 @@ class TestShellExpressionEvaluator < Minitest::Test
|
|
58
65
|
end
|
59
66
|
|
60
67
|
def test_single_expression
|
61
|
-
expressions = {
|
68
|
+
expressions = { 'greeting' => "echo 'Hello, World!'" }
|
62
69
|
result = evaluate_shell_expressions(@initial_code, expressions)
|
63
70
|
|
64
|
-
assert_equal
|
71
|
+
assert_equal 'Hello, World!', result['%<greeting>']
|
65
72
|
end
|
66
73
|
|
67
74
|
def test_multiple_expressions
|
68
75
|
expressions = {
|
69
|
-
|
70
|
-
|
71
|
-
|
76
|
+
'greeting' => "echo 'Hello, World!'",
|
77
|
+
'date' => 'date +%Y-%m-%d',
|
78
|
+
'kernel' => 'uname -r'
|
72
79
|
}
|
73
80
|
result = evaluate_shell_expressions(@initial_code, expressions)
|
74
81
|
|
75
|
-
assert_equal
|
76
|
-
assert_match
|
77
|
-
assert_match
|
82
|
+
assert_equal 'Hello, World!', result['%<greeting>']
|
83
|
+
assert_match(/\d{4}-\d{2}-\d{2}/, result['%<date>'])
|
84
|
+
assert_match(/\d+\.\d+\.\d+/, result['%<kernel>'])
|
78
85
|
end
|
79
86
|
|
80
87
|
def test_empty_expressions_list
|
@@ -85,13 +92,11 @@ class TestShellExpressionEvaluator < Minitest::Test
|
|
85
92
|
end
|
86
93
|
|
87
94
|
def test_invalid_expression
|
88
|
-
expressions = {
|
95
|
+
expressions = { 'invalid' => 'invalid_command' }
|
89
96
|
|
90
|
-
|
91
|
-
evaluate_shell_expressions(@initial_code, expressions)
|
92
|
-
end
|
97
|
+
result = evaluate_shell_expressions(@initial_code, expressions)
|
93
98
|
|
94
|
-
|
99
|
+
assert_equal EvaluateShellExpression::StatusFail, result
|
95
100
|
end
|
96
101
|
|
97
102
|
def test_initial_code_execution
|
@@ -99,17 +104,17 @@ class TestShellExpressionEvaluator < Minitest::Test
|
|
99
104
|
#!/bin/sh
|
100
105
|
echo "Custom setup message"
|
101
106
|
BASH
|
102
|
-
expressions = {
|
107
|
+
expressions = { 'test' => 'echo Test after initial setup' }
|
103
108
|
|
104
109
|
result = evaluate_shell_expressions(initial_code, expressions)
|
105
110
|
|
106
|
-
assert_equal
|
111
|
+
assert_equal 'Test after initial setup', result['%<test>']
|
107
112
|
end
|
108
113
|
|
109
114
|
def test_large_number_of_expressions
|
110
|
-
expressions = (1..100).map
|
115
|
+
expressions = (1..100).map do |i|
|
111
116
|
["expr_#{i}", "echo Expression #{i}"]
|
112
|
-
|
117
|
+
end.to_h
|
113
118
|
|
114
119
|
result = evaluate_shell_expressions(@initial_code, expressions)
|
115
120
|
|