markdown_exec 0.2.3 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +44 -13
- data/Gemfile.lock +1 -1
- data/README.md +103 -15
- data/lib/markdown_exec/version.rb +2 -2
- data/lib/markdown_exec.rb +325 -142
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8baa6b01b9d965c3a8856d08a86225457c09106c366ecd174f7f0e547f43f4a
|
4
|
+
data.tar.gz: bd0348f31ddb1bb0cda0328e5c7dd3187e6692269e8b132849833ce1d44f5b0f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e6f8028d4fe4dea45bacb14e8cb12306d0ee975ac729c04d0f8db990a6ce92758b13400329358656d5902c85dd5411aef717210b0151de4ae2cec375f51b0b98
|
7
|
+
data.tar.gz: 390dd965fe49ab4ac1651996fc7500ff971fbe71ce580ff807d8652b62aff5b50768ce971920e9f93682d5adb692cd5bcf99834b8b022c41734dc24f61cf940c
|
data/CHANGELOG.md
CHANGED
@@ -4,11 +4,9 @@
|
|
4
4
|
|
5
5
|
- pipe stdin to script
|
6
6
|
- yes/no/write/clipboard/record/edit/history
|
7
|
-
- add confirm block to generated file
|
8
7
|
- present timestamp, result of last exec for each command
|
9
8
|
- user settings
|
10
9
|
- hidden w , w/o () in names
|
11
|
-
- exit in menus
|
12
10
|
- fix regexp in pathnames
|
13
11
|
- tab completion from md file
|
14
12
|
- read file once to allow for tempdoc stream
|
@@ -20,18 +18,53 @@
|
|
20
18
|
|
21
19
|
- include blocks from local md file
|
22
20
|
|
23
|
-
- save outputs, errors
|
24
|
-
|
25
21
|
- chmod a+x logged script
|
26
22
|
|
27
|
-
-
|
23
|
+
- add shebang to saved script
|
24
|
+
|
25
|
+
## [0.2.6] - 2022-04-07
|
26
|
+
|
27
|
+
### Changed
|
28
|
+
|
29
|
+
- Fixed default values for command line options.
|
30
|
+
|
31
|
+
## [0.2.5] - 2022-04-03
|
28
32
|
|
29
|
-
|
30
|
-
|
33
|
+
### Added
|
34
|
+
|
35
|
+
- Command `--list-default-env` to show default configuration as environment variables.
|
36
|
+
- Command `--list-default-yaml` to show default configuration as YAML.
|
37
|
+
- Option to exit program when selecting files or blocks.
|
38
|
+
|
39
|
+
### Changed
|
31
40
|
|
32
|
-
|
41
|
+
- Composition of menu to facilitate reports.
|
42
|
+
- List default values in menu help.
|
33
43
|
|
34
|
-
## [0.2.
|
44
|
+
## [0.2.4] - 2022-04-01
|
45
|
+
|
46
|
+
### Added
|
47
|
+
|
48
|
+
- Command `--list-recent-scripts` to list the last *N* saved scripts.
|
49
|
+
- Command `--run-last-script` to re-run the last saved script.
|
50
|
+
- Command `--select-recent-script` to select and execute a recently saved script.
|
51
|
+
|
52
|
+
| YAML Name | Environment Variable | Option Name | Default | Purpose |
|
53
|
+
| :--- | :--- | :--- | :--- | :--- |
|
54
|
+
| list_count | MDE_LIST_COUNT | `--list-count` | `16` | Max. items to return in list |
|
55
|
+
| logged_stdout_filename_prefix | MDE_LOGGED_STDOUT_FILENAME_PREFIX | | `mde` | Name prefix for stdout files |
|
56
|
+
| save_execution_output | MDE_SAVE_EXECUTION_OUTPUT | `--save-execution-output` | False | Save standard output of the executed script |
|
57
|
+
| saved_script_filename_prefix | MDE_SAVED_SCRIPT_FILENAME_PREFIX | | `mde` | Name prefix for saved scripts |
|
58
|
+
| saved_script_folder | MDE_SAVED_SCRIPT_FOLDER | `--saved-script-folder` | `logs` | Saved script folder |
|
59
|
+
| saved_script_glob | MDE_SAVED_SCRIPT_GLOB | | `mde_*.sh` | Glob matching saved scripts |
|
60
|
+
| saved_stdout_folder | MDE_SAVED_STDOUT_FOLDER | `--saved-stdout-folder` | `logs` | Saved stdout folder |
|
61
|
+
|
62
|
+
### Changed
|
63
|
+
|
64
|
+
- Fix saving of executed script.
|
65
|
+
- Sort configuration keys output by `-0` (Show configuration.)
|
66
|
+
|
67
|
+
## [0.2.3] - 2022-03-29
|
35
68
|
|
36
69
|
### Added
|
37
70
|
|
@@ -45,9 +78,7 @@
|
|
45
78
|
### Changed
|
46
79
|
|
47
80
|
- Naming saved script files: The file name contains the time stamp, document name, and block name.
|
48
|
-
|
49
81
|
- Renamed folder with fixtures.
|
50
|
-
|
51
82
|
- Command options:
|
52
83
|
|
53
84
|
| YAML Name | Environment Variable | Option Name | Default | Purpose |
|
@@ -70,8 +101,8 @@
|
|
70
101
|
| block_name_excluded_match | MDE_BLOCK_NAME_EXCLUDED_MATCH | `^\(.+\)$` |
|
71
102
|
| block_name_match | MDE_BLOCK_NAME_MATCH | `:(?<title>\S+)( \|$)` |
|
72
103
|
| block_required_scan | MDE_BLOCK_REQUIRED_SCAN | `\+\S+` |
|
73
|
-
| fenced_start_and_end_match | MDE_FENCED_START_AND_END_MATCH |
|
74
|
-
| fenced_start_ex_match | MDE_FENCED_START_EX_MATCH |
|
104
|
+
| fenced_start_and_end_match | MDE_FENCED_START_AND_END_MATCH | ``^`{3,}`` |
|
105
|
+
| fenced_start_ex_match | MDE_FENCED_START_EX_MATCH | ``^`{3,}(?<shell>[^`\s]*) *(?<name>.*)$`` |
|
75
106
|
| heading1_match | MDE_HEADING1_MATCH | `^# *(?<name>[^#]*?) *$` |
|
76
107
|
| heading2_match | MDE_HEADING2_MATCH | `^## *(?<name>[^#]*?) *$` |
|
77
108
|
| heading3_match | MDE_HEADING3_MATCH | `^### *(?<name>.+?) *$` |
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,30 +1,35 @@
|
|
1
1
|
# MarkdownExec
|
2
2
|
|
3
|
-
Interactively select and execute fenced code blocks in markdown files. Build complex scripts by naming and requiring blocks.
|
3
|
+
Interactively select and execute fenced code blocks in markdown files. Build complex scripts by naming and requiring blocks. Log resulting scripts and output. Re-run scripts.
|
4
4
|
|
5
|
-
* Code blocks may be named.
|
5
|
+
* Code blocks may be named. Named blocks can be required by other blocks.
|
6
6
|
|
7
|
-
*
|
7
|
+
* The user-selected code block, and all required blocks, are arranged into a script in the order they appear in the markdown file. The script can be presented for approval prior to execution.
|
8
8
|
|
9
|
-
*
|
9
|
+
* Executed scripts can be saved. Saved scripts can be listed, selected, and executed.
|
10
10
|
|
11
|
-
*
|
11
|
+
* Output from executed scripts can be saved.
|
12
12
|
|
13
13
|
## Screenshots
|
14
14
|
|
15
15
|
### Select a file
|
16
|
+
|
16
17
|

|
17
18
|
|
18
19
|
### Select a block
|
20
|
+
|
19
21
|

|
20
22
|
|
21
23
|
### Approve code
|
24
|
+
|
22
25
|

|
23
26
|
|
24
27
|
### Output
|
28
|
+
|
25
29
|

|
26
30
|
|
27
31
|
### Example blocks
|
32
|
+
|
28
33
|

|
29
34
|
|
30
35
|
## Installation
|
@@ -34,39 +39,111 @@ Install:
|
|
34
39
|
|
35
40
|
## Usage
|
36
41
|
|
37
|
-
###
|
42
|
+
### Help
|
43
|
+
|
44
|
+
#### `mde --help`
|
45
|
+
|
38
46
|
Displays help information.
|
39
47
|
|
40
|
-
###
|
48
|
+
### Basic
|
49
|
+
|
50
|
+
#### `mde`
|
51
|
+
|
41
52
|
Process `README.md` file in the current folder. Displays all the blocks in the file and allows you to select using [up], [down], and [return]. Press [ctrl]-c to abort selection.
|
42
53
|
|
43
|
-
|
54
|
+
#### `mde my.md` or `mde -f my.md`
|
55
|
+
|
44
56
|
Select a block to execute from `my.md`.
|
45
57
|
|
46
|
-
|
58
|
+
#### `mde .` or `mde -p .`
|
47
59
|
|
48
60
|
Select a markdown file in the current folder. Select a block to execute from that file.
|
49
61
|
|
50
|
-
###
|
62
|
+
### Report documents and blocks
|
63
|
+
|
64
|
+
#### `mde --list-blocks`
|
65
|
+
|
51
66
|
List all blocks in the all the markdown documents in the current folder.
|
52
67
|
|
53
|
-
|
68
|
+
#### `mde --list-docs`
|
69
|
+
|
54
70
|
List all markdown documents in the current folder.
|
55
71
|
|
72
|
+
### Configuration
|
73
|
+
|
74
|
+
#### `mde --list-default-env` or `mde --list-default-yaml`
|
75
|
+
|
76
|
+
List default values that can be set in configuration file, environment, and command line.
|
77
|
+
|
78
|
+
#### `mde -0`
|
79
|
+
|
80
|
+
Show current configuation values that will be applied to the current run. Does not interrupt processing.
|
81
|
+
|
82
|
+
### Save scripts
|
83
|
+
|
84
|
+
#### `mde --save-executed-script 1`
|
85
|
+
|
86
|
+
Save executed script in saved script folder.
|
87
|
+
|
88
|
+
#### `mde --list-recent-scripts`
|
89
|
+
|
90
|
+
List recent saved scripts in saved script folder.
|
91
|
+
|
92
|
+
#### `mde --select-recent-script`
|
93
|
+
|
94
|
+
Select and execute a recently saved script in saved script folder.
|
95
|
+
|
96
|
+
### Save output
|
97
|
+
|
98
|
+
#### `mde --save-execution-output 1`
|
99
|
+
|
100
|
+
Save execution output in saved output folder.
|
101
|
+
|
56
102
|
## Behavior
|
103
|
+
|
57
104
|
* If no file and no folder are specified, blocks within `./README.md` are presented.
|
58
105
|
* If a file is specified, its blocks are presented.
|
59
106
|
* If a folder is specified, its files are presented. When a file is selected, its blocks are presented.
|
60
107
|
|
61
108
|
## Configuration
|
62
|
-
While starting up, reads the YAML configuration file `.mde.yml` in the current folder if it exists.
|
63
109
|
|
64
|
-
|
110
|
+
### Environment Variables
|
111
|
+
|
112
|
+
When executed, `mde` reads the current environment.
|
113
|
+
* Configuration in current and children shells, e.g. `export MDE_SAVE_EXECUTED_SCRIPT=1`.
|
114
|
+
* Configuration for the current command, e.g. `MDE_SAVE_EXECUTED_SCRIPT=1 mde`.
|
115
|
+
|
116
|
+
### Configuration Files
|
117
|
+
|
118
|
+
* Configuration in all shells, e.g. environment variables set in your user's `~/.bashrc` or `~/.bash_profile` files.
|
119
|
+
* Configuration in the optional file `.mde.yml` in the current folder. .e.g. `save_executed_script: true`
|
120
|
+
* Configuration in a YAML file and read while parsing the inputs, e.g. `--config my_path/my_file.yml`
|
65
121
|
|
66
|
-
|
67
|
-
|
122
|
+
### Program Arguments
|
123
|
+
|
124
|
+
* Configuration in command options, e.g. `mde --save-executed-script 1`
|
125
|
+
|
126
|
+
## Representing boolean values
|
127
|
+
|
128
|
+
Boolean values expressed as strings are interpreted as:
|
129
|
+
| String | Boolean |
|
130
|
+
| :---: | :---: |
|
131
|
+
| *empty string* | False |
|
132
|
+
| `0` | False |
|
133
|
+
| `1` | True |
|
134
|
+
| *anything else* | True |
|
135
|
+
|
136
|
+
E.g. `opt1=1` will set option `opt1` to True.
|
137
|
+
|
138
|
+
Boolean options configured with environment variables:
|
139
|
+
- Set to `1` or non-empty value to save executed scripts; empty or `0` to disable saving.
|
140
|
+
e.g. `export MDE_SAVE_EXECUTED_SCRIPT=1`
|
141
|
+
e.g. `export MDE_SAVE_EXECUTED_SCRIPT=`
|
142
|
+
- Specify variable on command line.
|
143
|
+
e.g. `MDE_SAVE_EXECUTED_SCRIPT=1 mde`
|
68
144
|
|
69
145
|
# Example blocks
|
146
|
+
|
70
147
|
When prompted, select either the `awake` or `asleep` block.
|
71
148
|
|
72
149
|
``` :(day)
|
@@ -89,6 +166,17 @@ export ACTIVITY=asleep
|
|
89
166
|
echo "$TIME -> $ACTIVITY"
|
90
167
|
```
|
91
168
|
|
169
|
+
``` :missing_command
|
170
|
+
fail
|
171
|
+
```
|
172
|
+
|
173
|
+
``` :exit_value
|
174
|
+
echo "a"
|
175
|
+
echo "b"
|
176
|
+
echo "c" >>/dev/stderr
|
177
|
+
grep nx Gemfile
|
178
|
+
```
|
179
|
+
|
92
180
|
# License
|
93
181
|
|
94
182
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/lib/markdown_exec.rb
CHANGED
@@ -14,21 +14,23 @@ require 'yaml'
|
|
14
14
|
# else true
|
15
15
|
|
16
16
|
def env_bool(name, default: false)
|
17
|
-
return default if (val = ENV[name]).nil?
|
17
|
+
return default if name.nil? || (val = ENV[name]).nil?
|
18
18
|
return false if val.empty? || val == '0'
|
19
19
|
|
20
20
|
true
|
21
21
|
end
|
22
22
|
|
23
23
|
def env_int(name, default: 0)
|
24
|
-
return default if (val = ENV[name]).nil?
|
24
|
+
return default if name.nil? || (val = ENV[name]).nil?
|
25
25
|
return default if val.empty?
|
26
26
|
|
27
27
|
val.to_i
|
28
28
|
end
|
29
29
|
|
30
30
|
def env_str(name, default: '')
|
31
|
-
ENV[name]
|
31
|
+
return default if name.nil? || (val = ENV[name]).nil?
|
32
|
+
|
33
|
+
val || default
|
32
34
|
end
|
33
35
|
|
34
36
|
$pdebug = env_bool 'MDE_DEBUG'
|
@@ -42,7 +44,12 @@ BLOCK_SIZE = 1024
|
|
42
44
|
|
43
45
|
class Object # rubocop:disable Style/Documentation
|
44
46
|
def present?
|
45
|
-
self
|
47
|
+
case self.class.to_s
|
48
|
+
when 'FalseClass', 'TrueClass'
|
49
|
+
true
|
50
|
+
else
|
51
|
+
self && (!respond_to?(:blank?) || !blank?)
|
52
|
+
end
|
46
53
|
end
|
47
54
|
end
|
48
55
|
|
@@ -94,45 +101,28 @@ module MarkdownExec
|
|
94
101
|
# options necessary to start, parse input, defaults for cli options
|
95
102
|
|
96
103
|
def base_options
|
97
|
-
|
98
|
-
#
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
save_executed_script: env_bool('MDE_SAVE_EXECUTED_SCRIPT', default: false), # option
|
109
|
-
saved_script_folder: env_str('MDE_SAVED_SCRIPT_FOLDER', default: 'logs'), # option
|
110
|
-
user_must_approve: env_bool('MDE_USER_MUST_APPROVE', default: true), # option Pause for user to approve script
|
111
|
-
|
112
|
-
# configuration options
|
113
|
-
block_name_excluded_match: env_str('MDE_BLOCK_NAME_EXCLUDED_MATCH', default: '^\(.+\)$'),
|
114
|
-
block_name_match: env_str('MDE_BLOCK_NAME_MATCH', default: ':(?<title>\S+)( |$)'),
|
115
|
-
block_required_scan: env_str('MDE_BLOCK_REQUIRED_SCAN', default: '\+\S+'),
|
116
|
-
fenced_start_and_end_match: env_str('MDE_FENCED_START_AND_END_MATCH', default: '^`{3,}'),
|
117
|
-
fenced_start_ex_match: env_str('MDE_FENCED_START_EX_MATCH', default: '^`{3,}(?<shell>[^`\s]*) *(?<name>.*)$'),
|
118
|
-
heading1_match: env_str('MDE_HEADING1_MATCH', default: '^# *(?<name>[^#]*?) *$'),
|
119
|
-
heading2_match: env_str('MDE_HEADING2_MATCH', default: '^## *(?<name>[^#]*?) *$'),
|
120
|
-
heading3_match: env_str('MDE_HEADING3_MATCH', default: '^### *(?<name>.+?) *$'),
|
121
|
-
md_filename_glob: env_str('MDE_MD_FILENAME_GLOB', default: '*.[Mm][Dd]'),
|
122
|
-
md_filename_match: env_str('MDE_MD_FILENAME_MATCH', default: '.+\\.md'),
|
123
|
-
mdheadings: true, # use headings (levels 1,2,3) in block lable
|
124
|
-
select_page_height: env_int('MDE_SELECT_PAGE_HEIGHT', default: 12)
|
125
|
-
}
|
104
|
+
menu_data
|
105
|
+
.map do |_long_name, _short_name, env_var, _arg_name, _description, opt_name, default, _proc1| # rubocop:disable Metrics/ParameterLists
|
106
|
+
next unless opt_name.present?
|
107
|
+
|
108
|
+
[opt_name, env_bool(env_var, default: value_for_hash(default))]
|
109
|
+
end.compact.to_h.merge(
|
110
|
+
{
|
111
|
+
mdheadings: true, # use headings (levels 1,2,3) in block lable
|
112
|
+
menu_with_exit: true
|
113
|
+
}
|
114
|
+
).tap_inspect format: :yaml
|
126
115
|
end
|
127
116
|
|
128
117
|
def default_options
|
129
118
|
{
|
130
119
|
bash: true, # bash block parsing in get_block_summary()
|
131
120
|
exclude_expect_blocks: true,
|
132
|
-
|
121
|
+
hide_blocks_by_name: true,
|
133
122
|
output_saved_script_filename: false,
|
134
|
-
|
135
|
-
|
123
|
+
prompt_approve_block: 'Process?',
|
124
|
+
prompt_select_block: 'Choose a block:',
|
125
|
+
prompt_select_md: 'Choose a file:',
|
136
126
|
saved_script_filename: nil, # calculated
|
137
127
|
struct: true # allow get_block_summary()
|
138
128
|
}
|
@@ -149,7 +139,7 @@ module MarkdownExec
|
|
149
139
|
display_command(opts, required_blocks) if opts[:output_script] || opts[:user_must_approve]
|
150
140
|
|
151
141
|
allow = true
|
152
|
-
allow = @prompt.yes?
|
142
|
+
allow = @prompt.yes? opts[:prompt_approve_block] if opts[:user_must_approve]
|
153
143
|
opts[:ir_approve] = allow
|
154
144
|
selected = get_block_by_name blocks_in_file, opts[:block_name]
|
155
145
|
|
@@ -171,6 +161,7 @@ module MarkdownExec
|
|
171
161
|
end
|
172
162
|
|
173
163
|
def command_execute(opts, cmd2)
|
164
|
+
@execute_files = Hash.new([])
|
174
165
|
@execute_options = opts
|
175
166
|
@execute_started_at = Time.now.utc
|
176
167
|
Open3.popen3(cmd2) do |stdin, stdout, stderr|
|
@@ -186,7 +177,6 @@ module MarkdownExec
|
|
186
177
|
# readable = ready[0]
|
187
178
|
# # writable = ready[1]
|
188
179
|
# # exceptions = ready[2]
|
189
|
-
@execute_files = Hash.new([])
|
190
180
|
ready.each.with_index do |readable, ind|
|
191
181
|
readable.each do |f|
|
192
182
|
block = f.read_nonblock(BLOCK_SIZE)
|
@@ -203,9 +193,11 @@ module MarkdownExec
|
|
203
193
|
@execute_completed_at = Time.now.utc
|
204
194
|
end
|
205
195
|
rescue Errno::ENOENT => e
|
196
|
+
# error triggered by missing command in script
|
206
197
|
@execute_aborted_at = Time.now.utc
|
207
198
|
@execute_error_message = e.message
|
208
199
|
@execute_error = e
|
200
|
+
@execute_files[1] = e.message
|
209
201
|
fout "Error ENOENT: #{e.inspect}"
|
210
202
|
end
|
211
203
|
|
@@ -222,37 +214,60 @@ module MarkdownExec
|
|
222
214
|
required_blocks.each { |cb| fout cb }
|
223
215
|
end
|
224
216
|
|
225
|
-
def exec_block(options,
|
217
|
+
def exec_block(options, _block_name = '')
|
226
218
|
options = default_options.merge options
|
227
219
|
update_options options, over: false
|
228
220
|
|
229
221
|
# document and block reports
|
230
222
|
#
|
231
223
|
files = list_files_per_options(options)
|
224
|
+
if @options[:list_blocks]
|
225
|
+
fout_list (files.map do |file|
|
226
|
+
make_block_labels(filename: file, struct: true)
|
227
|
+
end).flatten(1)
|
228
|
+
return
|
229
|
+
end
|
230
|
+
|
231
|
+
if @options[:list_default_yaml]
|
232
|
+
fout_list list_default_yaml
|
233
|
+
return
|
234
|
+
end
|
235
|
+
|
232
236
|
if @options[:list_docs]
|
233
237
|
fout_list files
|
234
238
|
return
|
235
239
|
end
|
236
240
|
|
237
|
-
if @options[:
|
238
|
-
fout_list
|
239
|
-
|
240
|
-
|
241
|
+
if @options[:list_default_env]
|
242
|
+
fout_list list_default_env
|
243
|
+
return
|
244
|
+
end
|
245
|
+
|
246
|
+
if @options[:list_recent_scripts]
|
247
|
+
fout_list list_recent_scripts
|
248
|
+
return
|
249
|
+
end
|
250
|
+
|
251
|
+
if @options[:run_last_script]
|
252
|
+
run_last_script
|
253
|
+
return
|
254
|
+
end
|
255
|
+
|
256
|
+
if @options[:select_recent_script]
|
257
|
+
select_recent_script
|
241
258
|
return
|
242
259
|
end
|
243
260
|
|
244
261
|
# process
|
245
262
|
#
|
263
|
+
@options[:filename] = select_md_file(files)
|
246
264
|
select_and_approve_block(
|
247
265
|
bash: true,
|
248
|
-
block_name: block_name,
|
249
|
-
filename: select_md_file(files),
|
250
266
|
struct: true
|
251
267
|
)
|
252
|
-
|
253
268
|
fout "saved_filespec: #{@execute_script_filespec}" if @options[:output_saved_script_filename]
|
254
|
-
|
255
|
-
output_execution_summary
|
269
|
+
save_execution_output
|
270
|
+
output_execution_summary
|
256
271
|
end
|
257
272
|
|
258
273
|
# standard output; not for debug
|
@@ -351,14 +366,37 @@ module MarkdownExec
|
|
351
366
|
blocks.tap_inspect
|
352
367
|
end
|
353
368
|
|
369
|
+
def list_default_env
|
370
|
+
menu_data
|
371
|
+
.map do |_long_name, _short_name, env_var, _arg_name, description, _opt_name, default, _proc1| # rubocop:disable Metrics/ParameterLists
|
372
|
+
next unless env_var.present?
|
373
|
+
|
374
|
+
[
|
375
|
+
"#{env_var}=#{value_for_cli default}",
|
376
|
+
description.present? ? description : nil
|
377
|
+
].compact.join(' # ')
|
378
|
+
end.compact.sort
|
379
|
+
end
|
380
|
+
|
381
|
+
def list_default_yaml
|
382
|
+
menu_data
|
383
|
+
.map do |_long_name, _short_name, _env_var, _arg_name, description, opt_name, default, _proc1| # rubocop:disable Metrics/ParameterLists
|
384
|
+
next unless opt_name.present? && default.present?
|
385
|
+
|
386
|
+
[
|
387
|
+
"#{opt_name}: #{value_for_yaml default}",
|
388
|
+
description.present? ? description : nil
|
389
|
+
].compact.join(' # ')
|
390
|
+
end.compact.sort
|
391
|
+
end
|
392
|
+
|
354
393
|
def list_files_per_options(options)
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
end.tap_inspect
|
394
|
+
list_files_specified(
|
395
|
+
options[:filename]&.present? ? options[:filename] : nil,
|
396
|
+
options[:path],
|
397
|
+
'README.md',
|
398
|
+
'.'
|
399
|
+
).tap_inspect
|
362
400
|
end
|
363
401
|
|
364
402
|
def list_files_specified(specified_filename, specified_folder, default_filename, default_folder, filetree = nil)
|
@@ -394,7 +432,7 @@ module MarkdownExec
|
|
394
432
|
opts = optsmerge call_options, options_block
|
395
433
|
block_name_excluded_match = Regexp.new opts[:block_name_excluded_match]
|
396
434
|
list_blocks_in_file(opts).map do |block|
|
397
|
-
next if opts[:
|
435
|
+
next if opts[:hide_blocks_by_name] && block[:name].match(block_name_excluded_match)
|
398
436
|
|
399
437
|
block
|
400
438
|
end.compact.tap_inspect
|
@@ -413,6 +451,11 @@ module MarkdownExec
|
|
413
451
|
.tap_inspect
|
414
452
|
end
|
415
453
|
|
454
|
+
def list_recent_scripts
|
455
|
+
Dir.glob(File.join(@options[:saved_script_folder],
|
456
|
+
@options[:saved_script_glob])).sort[0..(options[:list_count] - 1)].reverse.tap_inspect
|
457
|
+
end
|
458
|
+
|
416
459
|
def make_block_label(block, call_options = {})
|
417
460
|
opts = options.merge(call_options)
|
418
461
|
if opts[:mdheadings]
|
@@ -426,21 +469,117 @@ module MarkdownExec
|
|
426
469
|
def make_block_labels(call_options = {})
|
427
470
|
opts = options.merge(call_options)
|
428
471
|
list_blocks_in_file(opts).map do |block|
|
429
|
-
# next if opts[:
|
472
|
+
# next if opts[:hide_blocks_by_name] && block[:name].match(%r{^:\(.+\)$})
|
430
473
|
|
431
474
|
make_block_label block, opts
|
432
475
|
end.compact.tap_inspect
|
433
476
|
end
|
434
477
|
|
478
|
+
def menu_data
|
479
|
+
val_as_bool = ->(value) { value.to_i != 0 }
|
480
|
+
val_as_int = ->(value) { value.to_i }
|
481
|
+
val_as_str = ->(value) { value.to_s }
|
482
|
+
val_true = ->(_) { true }
|
483
|
+
|
484
|
+
summary_head = [
|
485
|
+
['config', nil, nil, 'PATH', 'Read configuration file', nil, '.', lambda { |value|
|
486
|
+
read_configuration_file! options, value
|
487
|
+
}],
|
488
|
+
['debug', 'd', 'MDE_DEBUG', 'BOOL', 'Debug output', nil, false, ->(value) { $pdebug = value.to_i != 0 }]
|
489
|
+
]
|
490
|
+
|
491
|
+
# rubocop:disable Layout/LineLength
|
492
|
+
summary_body = [
|
493
|
+
['filename', 'f', 'MDE_FILENAME', 'RELATIVE', 'Name of document', :filename, nil, val_as_str],
|
494
|
+
['list-blocks', nil, nil, nil, 'List blocks', :list_blocks, nil, val_true],
|
495
|
+
['list-count', nil, 'MDE_LIST_COUNT', 'NUM', 'Max. items to return in list', :list_count, 16, val_as_int],
|
496
|
+
['list-default-env', nil, nil, nil, 'List default configuration as environment variables', :list_default_env, nil, val_true],
|
497
|
+
['list-default-yaml', nil, nil, nil, 'List default configuration as YAML', :list_default_yaml, nil, val_true],
|
498
|
+
['list-docs', nil, nil, nil, 'List docs in current folder', :list_docs, nil, val_true],
|
499
|
+
['list-recent-scripts', nil, nil, nil, 'List recent saved scripts', :list_recent_scripts, nil, val_true],
|
500
|
+
['logged-stdout-filename-prefix', nil, 'MDE_LOGGED_STDOUT_FILENAME_PREFIX', 'NAME', 'Name prefix for stdout files', :logged_stdout_filename_prefix, 'mde', val_as_str],
|
501
|
+
['output-execution-summary', nil, 'MDE_OUTPUT_EXECUTION_SUMMARY', 'BOOL', 'Display summary for execution', :output_execution_summary, false, val_as_bool],
|
502
|
+
['output-script', nil, 'MDE_OUTPUT_SCRIPT', 'BOOL', 'Display script prior to execution', :output_script, false, val_as_bool],
|
503
|
+
['output-stdout', nil, 'MDE_OUTPUT_STDOUT', 'BOOL', 'Display standard output from execution', :output_stdout, true, val_as_bool],
|
504
|
+
['path', 'p', 'MDE_PATH', 'PATH', 'Path to documents', :path, nil, val_as_str],
|
505
|
+
['run-last-script', nil, nil, nil, 'Run most recently saved script', :run_last_script, nil, val_true],
|
506
|
+
['select-recent-script', nil, nil, nil, 'Select and execute a recently saved script', :select_recent_script, nil, val_true],
|
507
|
+
['save-executed-script', nil, 'MDE_SAVE_EXECUTED_SCRIPT', 'BOOL', 'Save executed script', :save_executed_script, false, val_as_bool],
|
508
|
+
['save-execution-output', nil, 'MDE_SAVE_EXECUTION_OUTPUT', 'BOOL', 'Save standard output of the executed script', :save_execution_output, false, val_as_bool],
|
509
|
+
['saved-script-filename-prefix', nil, 'MDE_SAVED_SCRIPT_FILENAME_PREFIX', 'NAME', 'Name prefix for saved scripts', :saved_script_filename_prefix, 'mde', val_as_str],
|
510
|
+
['saved-script-folder', nil, 'MDE_SAVED_SCRIPT_FOLDER', 'SPEC', 'Saved script folder', :saved_script_folder, 'logs', val_as_str],
|
511
|
+
['saved-script-glob', nil, 'MDE_SAVED_SCRIPT_GLOB', 'SPEC', 'Glob matching saved scripts', :saved_script_glob, 'mde_*.sh', val_as_str],
|
512
|
+
['saved-stdout-folder', nil, 'MDE_SAVED_STDOUT_FOLDER', 'SPEC', 'Saved stdout folder', :saved_stdout_folder, 'logs', val_as_str],
|
513
|
+
['user-must-approve', nil, 'MDE_USER_MUST_APPROVE', 'BOOL', 'Pause for user to approve script', :user_must_approve, true, val_as_bool]
|
514
|
+
]
|
515
|
+
# rubocop:enable Layout/LineLength
|
516
|
+
|
517
|
+
# rubocop:disable Style/Semicolon
|
518
|
+
summary_tail = [
|
519
|
+
[nil, '0', nil, nil, 'Show current configuration values',
|
520
|
+
nil, nil, ->(_) { options_finalize options; fout sorted_keys(options).to_yaml }],
|
521
|
+
['help', 'h', nil, nil, 'App help',
|
522
|
+
nil, nil, ->(_) { fout menu_help; exit }],
|
523
|
+
['version', 'v', nil, nil, 'App version',
|
524
|
+
nil, nil, ->(_) { fout MarkdownExec::VERSION; exit }],
|
525
|
+
['exit', 'x', nil, nil, 'Exit app',
|
526
|
+
nil, nil, ->(_) { exit }]
|
527
|
+
]
|
528
|
+
# rubocop:enable Style/Semicolon
|
529
|
+
|
530
|
+
env_vars = [
|
531
|
+
[nil, nil, 'MDE_BLOCK_NAME_EXCLUDED_MATCH', nil, 'Pattern for blocks to hide from user-selection',
|
532
|
+
:block_name_excluded_match, '^\(.+\)$', nil],
|
533
|
+
[nil, nil, 'MDE_BLOCK_NAME_MATCH', nil, '', :block_name_match, ':(?<title>\S+)( |$)', nil],
|
534
|
+
[nil, nil, 'MDE_BLOCK_REQUIRED_SCAN', nil, '', :block_required_scan, '\+\S+', nil],
|
535
|
+
[nil, nil, 'MDE_FENCED_START_AND_END_MATCH', nil, '', :fenced_start_and_end_match, '^`{3,}', nil],
|
536
|
+
[nil, nil, 'MDE_FENCED_START_EX_MATCH', nil, '', :fenced_start_ex_match,
|
537
|
+
'^`{3,}(?<shell>[^`\s]*) *(?<name>.*)$', nil],
|
538
|
+
[nil, nil, 'MDE_HEADING1_MATCH', nil, '', :heading1_match, '^# *(?<name>[^#]*?) *$', nil],
|
539
|
+
[nil, nil, 'MDE_HEADING2_MATCH', nil, '', :heading2_match, '^## *(?<name>[^#]*?) *$', nil],
|
540
|
+
[nil, nil, 'MDE_HEADING3_MATCH', nil, '', :heading3_match, '^### *(?<name>.+?) *$', nil],
|
541
|
+
[nil, nil, 'MDE_MD_FILENAME_GLOB', nil, '', :md_filename_glob, '*.[Mm][Dd]', nil],
|
542
|
+
[nil, nil, 'MDE_MD_FILENAME_MATCH', nil, '', :md_filename_match, '.+\\.md', nil],
|
543
|
+
[nil, nil, 'MDE_SELECT_PAGE_HEIGHT', nil, '', :select_page_height, 12, nil]
|
544
|
+
# [nil, nil, 'MDE_', nil, '', nil, '', nil],
|
545
|
+
]
|
546
|
+
|
547
|
+
summary_head + summary_body + summary_tail + env_vars
|
548
|
+
end
|
549
|
+
|
550
|
+
def menu_help
|
551
|
+
@option_parser.help
|
552
|
+
end
|
553
|
+
|
435
554
|
def option_exclude_blocks(opts, blocks)
|
436
555
|
block_name_excluded_match = Regexp.new opts[:block_name_excluded_match]
|
437
|
-
if opts[:
|
556
|
+
if opts[:hide_blocks_by_name]
|
438
557
|
blocks.reject { |block| block[:name].match(block_name_excluded_match) }
|
439
558
|
else
|
440
559
|
blocks
|
441
560
|
end
|
442
561
|
end
|
443
562
|
|
563
|
+
## post-parse options configuration
|
564
|
+
#
|
565
|
+
def options_finalize(rest)
|
566
|
+
## position 0: file or folder (optional)
|
567
|
+
#
|
568
|
+
if (pos = rest.fetch(0, nil))&.present?
|
569
|
+
if Dir.exist?(pos)
|
570
|
+
@options[:path] = pos
|
571
|
+
elsif File.exist?(pos)
|
572
|
+
@options[:filename] = pos
|
573
|
+
else
|
574
|
+
raise "Invalid parameter: #{pos}"
|
575
|
+
end
|
576
|
+
end
|
577
|
+
|
578
|
+
## position 1: block name (optional)
|
579
|
+
#
|
580
|
+
@options[:block_name] = rest.fetch(1, nil)
|
581
|
+
end
|
582
|
+
|
444
583
|
def optsmerge(call_options = {}, options_block = nil)
|
445
584
|
class_call_options = @options.merge(call_options || {})
|
446
585
|
if options_block
|
@@ -451,6 +590,8 @@ module MarkdownExec
|
|
451
590
|
end
|
452
591
|
|
453
592
|
def output_execution_summary
|
593
|
+
return unless @options[:output_execution_summary]
|
594
|
+
|
454
595
|
fout_section 'summary', {
|
455
596
|
execute_aborted_at: @execute_aborted_at,
|
456
597
|
execute_completed_at: @execute_completed_at,
|
@@ -463,6 +604,14 @@ module MarkdownExec
|
|
463
604
|
}
|
464
605
|
end
|
465
606
|
|
607
|
+
def prompt_with_quit(prompt_text, items, opts = {})
|
608
|
+
exit_option = '* Exit'
|
609
|
+
sel = @prompt.select prompt_text,
|
610
|
+
items + (@options[:menu_with_exit] ? [exit_option] : []),
|
611
|
+
opts
|
612
|
+
sel == exit_option ? nil : sel
|
613
|
+
end
|
614
|
+
|
466
615
|
def read_configuration_file!(options, configuration_path)
|
467
616
|
return unless File.exist?(configuration_path)
|
468
617
|
|
@@ -494,19 +643,11 @@ module MarkdownExec
|
|
494
643
|
#
|
495
644
|
@options = base_options
|
496
645
|
|
497
|
-
##
|
498
|
-
#
|
499
|
-
options_finalize = ->(_options) {}
|
500
|
-
|
501
|
-
proc_self = ->(value) { value }
|
502
|
-
proc_to_i = ->(value) { value.to_i != 0 }
|
503
|
-
proc_true = ->(_) { true }
|
504
|
-
|
505
|
-
# read local configuration file
|
646
|
+
## read local configuration file
|
506
647
|
#
|
507
648
|
read_configuration_file! @options, ".#{MarkdownExec::APP_NAME.downcase}.yml"
|
508
649
|
|
509
|
-
option_parser = OptionParser.new do |opts|
|
650
|
+
@option_parser = option_parser = OptionParser.new do |opts|
|
510
651
|
executable_name = File.basename($PROGRAM_NAME)
|
511
652
|
opts.banner = [
|
512
653
|
"#{MarkdownExec::APP_NAME}" \
|
@@ -514,55 +655,16 @@ module MarkdownExec
|
|
514
655
|
"Usage: #{executable_name} [path] [filename] [options]"
|
515
656
|
].join("\n")
|
516
657
|
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
summary_body = [
|
525
|
-
['filename', 'f', 'MDE_FILENAME', 'RELATIVE', 'Name of document',
|
526
|
-
:filename, proc_self],
|
527
|
-
['list-blocks', nil, nil, nil, 'List blocks',
|
528
|
-
:list_blocks, proc_true],
|
529
|
-
['list-docs', nil, nil, nil, 'List docs in current folder',
|
530
|
-
:list_docs, proc_true],
|
531
|
-
['output-execution-summary', nil, 'MDE_OUTPUT_EXECUTION_SUMMARY', 'BOOL', 'Display summary for execution',
|
532
|
-
:output_execution_summary, proc_to_i],
|
533
|
-
['output-script', nil, 'MDE_OUTPUT_SCRIPT', 'BOOL', 'Display script',
|
534
|
-
:output_script, proc_to_i],
|
535
|
-
['output-stdout', nil, 'MDE_OUTPUT_STDOUT', 'BOOL', 'Display standard output from execution',
|
536
|
-
:output_stdout, proc_to_i],
|
537
|
-
['path', 'p', 'MDE_PATH', 'PATH', 'Path to documents',
|
538
|
-
:path, proc_self],
|
539
|
-
['save-executed-script', nil, 'MDE_SAVE_EXECUTED_SCRIPT', 'BOOL', 'Save executed script',
|
540
|
-
:save_executed_script, proc_to_i],
|
541
|
-
['saved-script-folder', nil, 'MDE_SAVED_SCRIPT_FOLDER', 'SPEC', 'Saved script folder',
|
542
|
-
:saved_script_folder, proc_self],
|
543
|
-
['user-must-approve', nil, 'MDE_USER_MUST_APPROVE', 'BOOL', 'Pause to approve execution',
|
544
|
-
:user_must_approve, proc_to_i]
|
545
|
-
]
|
546
|
-
|
547
|
-
# rubocop:disable Style/Semicolon
|
548
|
-
summary_tail = [
|
549
|
-
[nil, '0', nil, nil, 'Show configuration',
|
550
|
-
nil, ->(_) { options_finalize.call options; fout options.to_yaml }],
|
551
|
-
['help', 'h', nil, nil, 'App help',
|
552
|
-
nil, ->(_) { fout option_parser.help; exit }],
|
553
|
-
['version', 'v', nil, nil, 'App version',
|
554
|
-
nil, ->(_) { fout MarkdownExec::VERSION; exit }],
|
555
|
-
['exit', 'x', nil, nil, 'Exit app',
|
556
|
-
nil, ->(_) { exit }]
|
557
|
-
]
|
558
|
-
# rubocop:enable Style/Semicolon
|
559
|
-
|
560
|
-
(summary_head + summary_body + summary_tail)
|
561
|
-
.map do |long_name, short_name, env_var, arg_name, description, opt_name, proc1| # rubocop:disable Metrics/ParameterLists
|
562
|
-
opts.on(*[long_name.present? ? "--#{long_name}#{arg_name.present? ? (' ' + arg_name) : ''}" : nil,
|
658
|
+
menu_data
|
659
|
+
.map do |long_name, short_name, _env_var, arg_name, description, opt_name, default, proc1| # rubocop:disable Metrics/ParameterLists
|
660
|
+
next unless long_name.present? || short_name.present?
|
661
|
+
|
662
|
+
opts.on(*[if long_name.present?
|
663
|
+
"--#{long_name}#{arg_name.present? ? " #{arg_name}" : ''}"
|
664
|
+
end,
|
563
665
|
short_name.present? ? "-#{short_name}" : nil,
|
564
666
|
[description,
|
565
|
-
|
667
|
+
default.present? ? "[#{value_for_cli default}]" : nil].compact.join(' '),
|
566
668
|
lambda { |value|
|
567
669
|
ret = proc1.call(value)
|
568
670
|
options[opt_name] = ret if opt_name
|
@@ -574,27 +676,43 @@ module MarkdownExec
|
|
574
676
|
option_parser.environment # env defaults to the basename of the program.
|
575
677
|
rest = option_parser.parse! # (into: options)
|
576
678
|
|
577
|
-
|
578
|
-
#
|
579
|
-
options_finalize.call options
|
679
|
+
options_finalize rest
|
580
680
|
|
581
|
-
|
582
|
-
|
583
|
-
if (pos = rest.fetch(0, nil))&.present?
|
584
|
-
if Dir.exist?(pos)
|
585
|
-
options[:path] = pos
|
586
|
-
elsif File.exist?(pos)
|
587
|
-
options[:filename] = pos
|
588
|
-
else
|
589
|
-
raise "Invalid parameter: #{pos}"
|
590
|
-
end
|
591
|
-
end
|
681
|
+
exec_block options, options[:block_name]
|
682
|
+
end
|
592
683
|
|
593
|
-
|
594
|
-
|
595
|
-
|
684
|
+
def run_last_script
|
685
|
+
filename = Dir.glob(File.join(@options[:saved_script_folder],
|
686
|
+
@options[:saved_script_glob])).sort[0..(options[:list_count] - 1)].last
|
687
|
+
filename.tap_inspect name: filename
|
688
|
+
mf = filename.match(/#{@options[:saved_script_filename_prefix]}_(?<time>[0-9\-]+)_(?<file>.+)_(?<block>.+)\.sh/)
|
596
689
|
|
597
|
-
|
690
|
+
@options[:block_name] = mf[:block]
|
691
|
+
@options[:filename] = "#{mf[:file]}.md" ### other extensions
|
692
|
+
@options[:save_executed_script] = false
|
693
|
+
select_and_approve_block
|
694
|
+
save_execution_output
|
695
|
+
output_execution_summary
|
696
|
+
end
|
697
|
+
|
698
|
+
def save_execution_output
|
699
|
+
return unless @options[:save_execution_output]
|
700
|
+
|
701
|
+
fne = File.basename(@options[:filename], '.*')
|
702
|
+
@options[:logged_stdout_filename] =
|
703
|
+
"#{[@options[:logged_stdout_filename_prefix], Time.now.utc.strftime('%F-%H-%M-%S'), fne,
|
704
|
+
@options[:block_name]].join('_')}.out.txt"
|
705
|
+
@options[:logged_stdout_filespec] = File.join @options[:saved_stdout_folder], @options[:logged_stdout_filename]
|
706
|
+
@logged_stdout_filespec = @options[:logged_stdout_filespec]
|
707
|
+
dirname = File.dirname(@options[:logged_stdout_filespec])
|
708
|
+
Dir.mkdir dirname unless File.exist?(dirname)
|
709
|
+
File.write(@options[:logged_stdout_filespec], @execute_files&.fetch(0, ''))
|
710
|
+
# @options[:logged_stderr_filename] =
|
711
|
+
# "#{[@options[:logged_stdout_filename_prefix], Time.now.utc.strftime('%F-%H-%M-%S'), fne,
|
712
|
+
# @options[:block_name]].join('_')}.err.txt"
|
713
|
+
# @options[:logged_stderr_filespec] = File.join @options[:saved_stdout_folder], @options[:logged_stderr_filename]
|
714
|
+
# @logged_stderr_filespec = @options[:logged_stderr_filespec]
|
715
|
+
# File.write(@options[:logged_stderr_filespec], @execute_files&.fetch(1, ''))
|
598
716
|
end
|
599
717
|
|
600
718
|
def select_and_approve_block(call_options = {}, &options_block)
|
@@ -608,9 +726,11 @@ module MarkdownExec
|
|
608
726
|
|
609
727
|
return nil if block_labels.count.zero?
|
610
728
|
|
611
|
-
sel =
|
729
|
+
sel = prompt_with_quit pt, block_labels, per_page: opts[:select_page_height]
|
730
|
+
return nil if sel.nil?
|
731
|
+
|
612
732
|
label_block = blocks_in_file.select { |block| block[:label] == sel }.fetch(0, nil)
|
613
|
-
opts[:block_name] = label_block[:name]
|
733
|
+
opts[:block_name] = @options[:block_name] = label_block[:name]
|
614
734
|
end
|
615
735
|
|
616
736
|
approve_block opts, blocks_in_file
|
@@ -622,10 +742,32 @@ module MarkdownExec
|
|
622
742
|
if files.count == 1
|
623
743
|
files[0]
|
624
744
|
elsif files.count >= 2
|
625
|
-
|
745
|
+
prompt_with_quit opts[:prompt_select_md].to_s, files, per_page: opts[:select_page_height]
|
626
746
|
end
|
627
747
|
end
|
628
748
|
|
749
|
+
def select_recent_script
|
750
|
+
filename = prompt_with_quit @options[:prompt_select_md].to_s, list_recent_scripts,
|
751
|
+
per_page: @options[:select_page_height]
|
752
|
+
return if filename.nil?
|
753
|
+
|
754
|
+
mf = filename.match(/#{@options[:saved_script_filename_prefix]}_(?<time>[0-9\-]+)_(?<file>.+)_(?<block>.+)\.sh/)
|
755
|
+
|
756
|
+
@options[:block_name] = mf[:block]
|
757
|
+
@options[:filename] = "#{mf[:file]}.md" ### other extensions
|
758
|
+
select_and_approve_block(
|
759
|
+
bash: true,
|
760
|
+
save_executed_script: false,
|
761
|
+
struct: true
|
762
|
+
)
|
763
|
+
save_execution_output
|
764
|
+
output_execution_summary
|
765
|
+
end
|
766
|
+
|
767
|
+
def sorted_keys(hash1)
|
768
|
+
hash1.keys.sort.to_h { |k| [k, hash1[k]] }
|
769
|
+
end
|
770
|
+
|
629
771
|
def summarize_block(headings, title)
|
630
772
|
{ headings: headings, name: title, title: title }
|
631
773
|
end
|
@@ -636,16 +778,57 @@ module MarkdownExec
|
|
636
778
|
else
|
637
779
|
@options.merge! opts
|
638
780
|
end
|
639
|
-
@options
|
781
|
+
@options.tap_inspect format: :yaml
|
640
782
|
end
|
641
783
|
|
642
|
-
def
|
643
|
-
|
784
|
+
def value_for_cli(value)
|
785
|
+
case value.class.to_s
|
786
|
+
when 'String'
|
787
|
+
"'#{value}'"
|
788
|
+
when 'FalseClass', 'TrueClass'
|
789
|
+
value ? '1' : '0'
|
790
|
+
when 'Integer'
|
791
|
+
value
|
792
|
+
else
|
793
|
+
value.to_s
|
794
|
+
end
|
795
|
+
end
|
796
|
+
|
797
|
+
def value_for_hash(value, default = nil)
|
798
|
+
return default if value.nil?
|
644
799
|
|
645
|
-
|
646
|
-
|
647
|
-
|
800
|
+
case value.class.to_s
|
801
|
+
when 'String', 'Integer', 'FalseClass', 'TrueClass'
|
802
|
+
value
|
803
|
+
when value.empty?
|
804
|
+
default
|
805
|
+
else
|
806
|
+
value.to_s
|
807
|
+
end
|
808
|
+
end
|
648
809
|
|
810
|
+
def value_for_yaml(value)
|
811
|
+
return default if value.nil?
|
812
|
+
|
813
|
+
case value.class.to_s
|
814
|
+
when 'String'
|
815
|
+
"'#{value}'"
|
816
|
+
when 'Integer'
|
817
|
+
value
|
818
|
+
when 'FalseClass', 'TrueClass'
|
819
|
+
value ? true : false
|
820
|
+
when value.empty?
|
821
|
+
default
|
822
|
+
else
|
823
|
+
value.to_s
|
824
|
+
end
|
825
|
+
end
|
826
|
+
|
827
|
+
def write_command_file(opts, required_blocks)
|
828
|
+
fne = File.basename(opts[:filename], '.*')
|
829
|
+
opts[:saved_script_filename] =
|
830
|
+
"#{[opts[:saved_script_filename_prefix], Time.now.utc.strftime('%F-%H-%M-%S'), fne,
|
831
|
+
opts[:block_name]].join('_')}.sh"
|
649
832
|
@options[:saved_filespec] = File.join opts[:saved_script_folder], opts[:saved_script_filename]
|
650
833
|
@execute_script_filespec = @options[:saved_filespec]
|
651
834
|
dirname = File.dirname(@options[:saved_filespec])
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: markdown_exec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fareed Stevenson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-04-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: open3
|
@@ -67,7 +67,8 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 0.2.0
|
69
69
|
description: Interactively select and execute fenced code blocks in markdown files.
|
70
|
-
Build complex scripts by naming and requiring blocks.
|
70
|
+
Build complex scripts by naming and requiring blocks. Log resulting scripts and
|
71
|
+
output. Re-run scripts.
|
71
72
|
email:
|
72
73
|
- fareed@phomento.com
|
73
74
|
executables:
|
@@ -127,5 +128,5 @@ requirements: []
|
|
127
128
|
rubygems_version: 3.2.32
|
128
129
|
signing_key:
|
129
130
|
specification_version: 4
|
130
|
-
summary:
|
131
|
+
summary: Interactively select and execute fenced code blocks in markdown files.
|
131
132
|
test_files: []
|