markdown_exec 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +16 -4
- data/CHANGELOG.md +28 -0
- data/Gemfile.lock +1 -1
- data/Rakefile +32 -8
- data/bats/bats.bats +33 -0
- data/bats/block-types.bats +56 -0
- data/bats/cli.bats +74 -0
- data/bats/fail.bats +11 -0
- data/bats/history.bats +34 -0
- data/bats/markup.bats +66 -0
- data/bats/mde.bats +29 -0
- data/bats/options.bats +92 -0
- data/bats/test_helper.bash +152 -0
- data/bin/tab_completion.sh +44 -20
- data/docs/dev/block-type-opts.md +10 -0
- data/docs/dev/block-type-port.md +24 -0
- data/docs/dev/block-type-vars.md +7 -0
- data/docs/dev/pass-through-arguments.md +8 -0
- data/docs/dev/specs-import.md +9 -0
- data/docs/dev/specs.md +83 -0
- data/docs/dev/text-decoration.md +7 -0
- data/examples/bash-blocks.md +4 -4
- data/examples/block-names.md +40 -5
- data/examples/import0.md +23 -0
- data/examples/import1.md +13 -0
- data/examples/link-blocks-vars.md +3 -3
- data/examples/opts-blocks-require.md +6 -6
- data/examples/table-markup.md +31 -0
- data/examples/text-markup.md +58 -0
- data/examples/vars-blocks.md +2 -2
- data/examples/wrap.md +87 -9
- data/lib/ansi_formatter.rb +12 -6
- data/lib/ansi_string.rb +153 -0
- data/lib/argument_processor.rb +160 -0
- data/lib/cached_nested_file_reader.rb +4 -2
- data/lib/ce_get_cost_and_usage.rb +4 -3
- data/lib/cli.rb +1 -1
- data/lib/colorize.rb +41 -0
- data/lib/constants.rb +17 -0
- data/lib/directory_searcher.rb +4 -2
- data/lib/doh.rb +190 -0
- data/lib/env.rb +1 -1
- data/lib/exceptions.rb +9 -6
- data/lib/fcb.rb +0 -199
- data/lib/filter.rb +18 -5
- data/lib/find_files.rb +8 -3
- data/lib/format_table.rb +406 -0
- data/lib/hash_delegator.rb +939 -611
- data/lib/hierarchy_string.rb +221 -0
- data/lib/input_sequencer.rb +19 -11
- data/lib/instance_method_wrapper.rb +2 -1
- data/lib/layered_hash.rb +143 -0
- data/lib/link_history.rb +22 -8
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +420 -165
- data/lib/mdoc.rb +38 -38
- data/lib/menu.src.yml +832 -680
- data/lib/menu.yml +814 -689
- data/lib/namer.rb +6 -12
- data/lib/object_present.rb +1 -1
- data/lib/option_value.rb +7 -3
- data/lib/poly.rb +33 -14
- data/lib/resize_terminal.rb +60 -52
- data/lib/saved_assets.rb +45 -34
- data/lib/saved_files_matcher.rb +6 -3
- data/lib/streams_out.rb +7 -1
- data/lib/table_extractor.rb +166 -0
- data/lib/tap.rb +5 -6
- data/lib/text_analyzer.rb +236 -0
- metadata +28 -3
- data/lib/std_out_err_logger.rb +0 -119
data/lib/namer.rb
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
|
4
4
|
# encoding=utf-8
|
5
5
|
require 'digest'
|
6
|
-
# require_relative 'poly'
|
7
6
|
|
8
7
|
$pd = false unless defined?($pd)
|
9
8
|
|
@@ -11,7 +10,9 @@ class Hash
|
|
11
10
|
# block name in commands and documents
|
12
11
|
def pub_name(**kwargs)
|
13
12
|
full = fetch(:nickname, nil) || fetch(:oname, nil)
|
14
|
-
full&.to_s&.pub_name(**kwargs).tap { |ret|
|
13
|
+
full&.to_s&.pub_name(**kwargs).tap { |ret|
|
14
|
+
pp [__LINE__, 'Hash.pub_name() ->', ret] if $pd
|
15
|
+
}
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
@@ -36,15 +37,8 @@ class String
|
|
36
37
|
self
|
37
38
|
end
|
38
39
|
|
39
|
-
trimmed.gsub(pattern, replacement).tap { |ret|
|
40
|
+
trimmed.gsub(pattern, replacement).tap { |ret|
|
41
|
+
pp [__LINE__, 'String.pub_name() ->', ret] if $pd
|
42
|
+
}
|
40
43
|
end
|
41
44
|
end
|
42
|
-
|
43
|
-
# require 'ostruct'
|
44
|
-
|
45
|
-
# class BlkS < OpenStruct
|
46
|
-
# # Method to fetch the value associated with the attribute :nickname or :oname
|
47
|
-
# def pub_name
|
48
|
-
# self.nickname || self.oname
|
49
|
-
# end
|
50
|
-
# end
|
data/lib/object_present.rb
CHANGED
data/lib/option_value.rb
CHANGED
@@ -16,7 +16,7 @@ module MarkdownExec
|
|
16
16
|
return default if value.nil?
|
17
17
|
|
18
18
|
case value
|
19
|
-
when String, Integer
|
19
|
+
when String, Integer, Array, Hash
|
20
20
|
value
|
21
21
|
when TrueClass, FalseClass
|
22
22
|
value ? true : false
|
@@ -64,8 +64,12 @@ if $PROGRAM_NAME == __FILE__
|
|
64
64
|
assert_equal false, MarkdownExec::OptionValue.for_hash(false)
|
65
65
|
end
|
66
66
|
|
67
|
-
def
|
68
|
-
assert_equal
|
67
|
+
def test_for_hash_with_empty_array
|
68
|
+
assert_equal [], MarkdownExec::OptionValue.for_hash([], 'default')
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_for_hash_with_empty_hash
|
72
|
+
assert_equal({}, MarkdownExec::OptionValue.for_hash({}, 'default'))
|
69
73
|
end
|
70
74
|
|
71
75
|
def test_for_yaml_with_string
|
data/lib/poly.rb
CHANGED
@@ -8,7 +8,9 @@ $pd = false
|
|
8
8
|
class Poly
|
9
9
|
# attr_reader :table
|
10
10
|
def initialize(table = {})
|
11
|
-
@table = table.tap{|ret|
|
11
|
+
@table = table.tap { |ret|
|
12
|
+
pp [__LINE__, 'Poly.initialize()', 'table', table.to_yaml] if $pd
|
13
|
+
}
|
12
14
|
end
|
13
15
|
|
14
16
|
def fetch(key, *args)
|
@@ -20,16 +22,21 @@ class Poly
|
|
20
22
|
elsif block_given?
|
21
23
|
yield key_sym
|
22
24
|
elsif args.count.positive?
|
23
|
-
# binding.irb
|
25
|
+
# binding.irb
|
24
26
|
args.first
|
25
27
|
else
|
26
|
-
binding.irb
|
28
|
+
binding.irb
|
27
29
|
raise KeyError, "key not found: #{key}"
|
28
|
-
end.tap{|ret|
|
30
|
+
end.tap { |ret|
|
31
|
+
pp([__LINE__, "Poly.fetch #{key} #{args}", '->',
|
32
|
+
ret]) if $pd
|
33
|
+
}
|
29
34
|
end
|
30
35
|
|
31
36
|
def key?(name)
|
32
|
-
@table.key?(name.to_sym).tap{|ret|
|
37
|
+
@table.key?(name.to_sym).tap { |ret|
|
38
|
+
pp([__LINE__, "Poly.key? #{name}", '->', ret]) if $pd
|
39
|
+
}
|
33
40
|
end
|
34
41
|
|
35
42
|
def method_missing(name, *args)
|
@@ -55,12 +62,17 @@ binding.irb
|
|
55
62
|
else
|
56
63
|
pt = 'table read'
|
57
64
|
@table[name.to_sym]
|
58
|
-
end.tap{|ret|
|
65
|
+
end.tap { |ret|
|
66
|
+
pp([__LINE__,
|
67
|
+
"Poly.method_missing #{name} #{args.map(&:to_s).join(' ')}", pt, '->', ret]) if $pd
|
68
|
+
}
|
59
69
|
end
|
60
70
|
|
61
71
|
def respond_to_missing?(name, include_private = false)
|
62
72
|
# name.to_s.end_with?('=') || @table.key?(name.to_sym) || @table.respond_to?(name) || super
|
63
|
-
(name.to_s.end_with?('=') || @table.key?(name.to_sym) || @table.respond_to?(name) || super).tap{|ret|
|
73
|
+
(name.to_s.end_with?('=') || @table.key?(name.to_sym) || @table.respond_to?(name) || super).tap { |ret|
|
74
|
+
pp([__LINE__, "Poly.respond_to_missing? #{name}", '->', ret]) if $pd
|
75
|
+
}
|
64
76
|
end
|
65
77
|
|
66
78
|
def [](key)
|
@@ -68,7 +80,7 @@ binding.irb
|
|
68
80
|
send("get_#{key}")
|
69
81
|
else
|
70
82
|
@table[key.to_sym]
|
71
|
-
end.tap{|ret| pp([__LINE__,"Poly.[] #{key}",'->',ret]) if $pd }
|
83
|
+
end.tap { |ret| pp([__LINE__, "Poly.[] #{key}", '->', ret]) if $pd }
|
72
84
|
end
|
73
85
|
|
74
86
|
def []=(key, value)
|
@@ -76,7 +88,10 @@ binding.irb
|
|
76
88
|
send("set_#{key}", value)
|
77
89
|
else
|
78
90
|
@table[key.to_sym] = value
|
79
|
-
end.tap{|ret|
|
91
|
+
end.tap { |ret|
|
92
|
+
pp([__LINE__, "Poly.[]= #{key} #{value}", '->',
|
93
|
+
ret]) if $pd
|
94
|
+
}
|
80
95
|
end
|
81
96
|
|
82
97
|
# for export to Prompt library
|
@@ -84,18 +99,22 @@ binding.irb
|
|
84
99
|
# Proc.new { |x| @table.merge x }
|
85
100
|
# end
|
86
101
|
def merge(*args)
|
87
|
-
# pp caller
|
88
|
-
# binding.irb
|
89
|
-
@table.merge(*args).tap{|ret|
|
102
|
+
# pp caller
|
103
|
+
# binding.irb
|
104
|
+
@table.merge(*args).tap { |ret|
|
105
|
+
pp([__LINE__, "Poly.merge", '->', ret]) if $pd
|
106
|
+
}
|
90
107
|
end
|
91
108
|
|
92
109
|
# for export to Prompt library
|
93
110
|
def to_h
|
94
|
-
@table.tap{|ret| pp([__LINE__,"Poly.to_h",'->',ret]) if $pd }
|
111
|
+
@table.tap { |ret| pp([__LINE__, "Poly.to_h", '->', ret]) if $pd }
|
95
112
|
end
|
96
113
|
|
97
114
|
def to_yaml
|
98
|
-
@table.to_yaml.tap{|ret|
|
115
|
+
@table.to_yaml.tap { |ret|
|
116
|
+
pp([__LINE__, "Poly.to_yaml", '->', ret]) if $pd
|
117
|
+
}
|
99
118
|
end
|
100
119
|
end
|
101
120
|
|
data/lib/resize_terminal.rb
CHANGED
@@ -10,60 +10,66 @@ require 'timeout'
|
|
10
10
|
# If so, it sends escape sequences to query the terminal size and reads the response.
|
11
11
|
# It then compares the current terminal size with the calculated size and adjusts if necessary.
|
12
12
|
# If the terminal emulator is unsupported, it prints an error message.
|
13
|
-
|
13
|
+
# 2024-8-23 add require_stdout to allow for testing
|
14
|
+
def resize_terminal(show_dims: false, show_rectangle: false,
|
15
|
+
require_stdout: true)
|
14
16
|
# Check if running in an interactive terminal and no arguments are provided
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
$stdout.flush
|
20
|
-
|
21
|
-
# Read the response from the terminal
|
22
|
-
response = String.new
|
23
|
-
Timeout.timeout(5) do
|
24
|
-
loop do
|
25
|
-
char = $stdin.getch
|
26
|
-
response << char
|
27
|
-
break if response.include?('R')
|
28
|
-
end
|
29
|
-
end
|
17
|
+
unless $stdin.tty?
|
18
|
+
warn 'Usage: resize_terminal'
|
19
|
+
return
|
20
|
+
end
|
30
21
|
|
31
|
-
|
32
|
-
warn "Error: No response received from terminal. Response: #{response.inspect}"
|
33
|
-
return 1
|
34
|
-
end
|
22
|
+
return if require_stdout && !$stdout.tty?
|
35
23
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
24
|
+
# Save the current state and send the escape sequence to get the cursor position
|
25
|
+
print "\e7\e[r\e[999;999H\e[6n\e8"
|
26
|
+
$stdout.flush
|
27
|
+
|
28
|
+
# Read the response from the terminal
|
29
|
+
response = String.new
|
30
|
+
Timeout.timeout(5) do
|
31
|
+
loop do
|
32
|
+
char = $stdin.getch
|
33
|
+
response << char
|
34
|
+
break if response.include?('R')
|
35
|
+
end
|
36
|
+
end
|
42
37
|
|
43
|
-
|
38
|
+
if response.empty?
|
39
|
+
warn "Error: No response received from terminal. Response: #{response.inspect}"
|
40
|
+
return 1
|
41
|
+
end
|
44
42
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
warn "Error: Calculated terminal size is invalid. Columns: #{calculated_columns}, Rows: #{calculated_rows}"
|
52
|
-
return 1
|
53
|
-
end
|
43
|
+
# Match the response to extract the terminal dimensions
|
44
|
+
match_data = response.match(/\[(\d+);(\d+)R/)
|
45
|
+
unless match_data
|
46
|
+
warn "Error: Failed to match terminal response pattern. Response: #{response.inspect}"
|
47
|
+
return 1
|
48
|
+
end
|
54
49
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
50
|
+
calculated_rows, calculated_columns = match_data.captures.map(&:to_i)
|
51
|
+
|
52
|
+
if ENV['COLUMNS'].to_i == calculated_columns && ENV['LINES'].to_i == calculated_rows
|
53
|
+
puts "#{ENV.fetch('TERM', nil)} #{calculated_columns}x#{calculated_rows}"
|
54
|
+
elsif calculated_columns.positive? && calculated_rows.positive?
|
55
|
+
warn "#{ENV.fetch('COLUMNS',
|
56
|
+
nil)}x#{ENV.fetch('LINES',
|
57
|
+
nil)} -> #{calculated_columns}x#{calculated_rows}" if show_dims
|
58
|
+
system("stty cols #{calculated_columns} rows #{calculated_rows}")
|
64
59
|
else
|
65
|
-
warn
|
60
|
+
warn "Error: Calculated terminal size is invalid. Columns: #{calculated_columns}, Rows: #{calculated_rows}"
|
61
|
+
return 1
|
66
62
|
end
|
63
|
+
|
64
|
+
# Display a text rectangle if the option is enabled
|
65
|
+
display_terminal_rectangle(calculated_columns,
|
66
|
+
calculated_rows) if show_rectangle
|
67
|
+
rescue Timeout::Error
|
68
|
+
warn 'Error: Timeout while reading terminal response. Unsupported terminal emulator.'
|
69
|
+
1
|
70
|
+
rescue StandardError => err
|
71
|
+
warn "Error: #{err.message}. Unsupported terminal emulator."
|
72
|
+
1
|
67
73
|
end
|
68
74
|
|
69
75
|
# This function draws a rectangle of the given width and height
|
@@ -119,7 +125,7 @@ class ResizeTerminalTest < Minitest::Test
|
|
119
125
|
$stdin.stub(:getch, -> { response.slice!(0) || '' }) do
|
120
126
|
assert_output("\e7\e[r\e[999;999H\e[6n\e8xterm-256color #{columns}x24\n") do
|
121
127
|
# assert_output('', '') do
|
122
|
-
resize_terminal
|
128
|
+
resize_terminal(require_stdout: false)
|
123
129
|
end
|
124
130
|
end
|
125
131
|
end
|
@@ -131,8 +137,9 @@ class ResizeTerminalTest < Minitest::Test
|
|
131
137
|
ARGV.replace([])
|
132
138
|
$stdin.stub(:getch, -> { '' }) do
|
133
139
|
# assert_output(nil, /Error: No response received from terminal/) do
|
134
|
-
assert_output(nil,
|
135
|
-
|
140
|
+
assert_output(nil,
|
141
|
+
"Error: Timeout while reading terminal response. Unsupported terminal emulator.\n") do
|
142
|
+
assert_equal 1, resize_terminal(require_stdout: false)
|
136
143
|
end
|
137
144
|
end
|
138
145
|
end
|
@@ -144,8 +151,9 @@ class ResizeTerminalTest < Minitest::Test
|
|
144
151
|
ARGV.replace([])
|
145
152
|
response = "\e[999;999H\e[6n\e[InvalidResponse".dup
|
146
153
|
$stdin.stub(:getch, -> { response.slice!(0) || '' }) do
|
147
|
-
assert_output(nil,
|
148
|
-
|
154
|
+
assert_output(nil,
|
155
|
+
/Error: Failed to match terminal response pattern/) do
|
156
|
+
assert_equal 1, resize_terminal(require_stdout: false)
|
149
157
|
end
|
150
158
|
end
|
151
159
|
end
|
@@ -157,7 +165,7 @@ class ResizeTerminalTest < Minitest::Test
|
|
157
165
|
ARGV.replace([])
|
158
166
|
Timeout.stub(:timeout, ->(_) { raise Timeout::Error }) do
|
159
167
|
assert_output(nil, /Error: Timeout while reading terminal response/) do
|
160
|
-
assert_equal 1, resize_terminal
|
168
|
+
assert_equal 1, resize_terminal(require_stdout: false)
|
161
169
|
end
|
162
170
|
end
|
163
171
|
end
|
data/lib/saved_assets.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
# encoding=utf-8
|
5
5
|
require_relative 'namer'
|
6
|
+
require_relative 'object_present'
|
6
7
|
|
7
8
|
module MarkdownExec
|
8
9
|
# SavedAsset
|
@@ -25,16 +26,15 @@ module MarkdownExec
|
|
25
26
|
# @param ftime [String] the time format (default: DEFAULT_FTIME)
|
26
27
|
# @param exts [String] the extension to append (default: '.sh')
|
27
28
|
def initialize(
|
28
|
-
saved_asset_format:,
|
29
|
-
ftime: DEFAULT_FTIME,
|
30
|
-
mark: nil,
|
29
|
+
saved_asset_format:, blockname: nil, exts: nil,
|
30
|
+
filename: nil, ftime: DEFAULT_FTIME, join_str: nil,
|
31
|
+
mark: nil, prefix: nil, time: nil
|
31
32
|
)
|
32
|
-
@filename = filename ? filename.pub_name : '*'
|
33
|
-
@prefix = prefix || '*'
|
34
|
-
@time = time ? time.strftime(ftime) : '*'
|
35
|
-
@blockname = blockname ? blockname.pub_name : '*'
|
36
|
-
|
37
|
-
@exts = exts || '.*' # [String] the extension to append (default: '.sh')
|
33
|
+
@filename = filename.present? ? filename.pub_name : '*'
|
34
|
+
@prefix = prefix || '*'
|
35
|
+
@time = time ? time.strftime(ftime) : '*'
|
36
|
+
@blockname = blockname ? blockname.pub_name : '*'
|
37
|
+
@exts = exts || '.*'
|
38
38
|
@mark = mark || MARK_STR
|
39
39
|
@join_str = join_str || JOIN_STR
|
40
40
|
@saved_asset_format = saved_asset_format
|
@@ -64,6 +64,9 @@ return if $PROGRAM_NAME != __FILE__
|
|
64
64
|
|
65
65
|
require 'minitest/autorun'
|
66
66
|
|
67
|
+
SAVED_ASSET_FORMAT = '%{prefix}%{join}%{time}%{join}%{filename}%{join}' \
|
68
|
+
'%{mark}%{join}%{blockname}%{join}%{exts}'
|
69
|
+
|
67
70
|
class SavedAssetTest < Minitest::Test
|
68
71
|
def test_script_name_with_special_characters_in_blockname
|
69
72
|
filename = 'sample.txt'
|
@@ -71,10 +74,11 @@ class SavedAssetTest < Minitest::Test
|
|
71
74
|
time = Time.new(2023, 1, 1, 12, 0, 0)
|
72
75
|
blockname = 'block/1:2'
|
73
76
|
|
74
|
-
expected_name = 'test_2023-01-01-12-00-00_sample_txt_
|
75
|
-
assert_equal expected_name, MarkdownExec::SavedAsset.
|
76
|
-
filename: filename, prefix: prefix,
|
77
|
-
|
77
|
+
expected_name = 'test_2023-01-01-12-00-00_sample_txt_~_block_1_2_.*'
|
78
|
+
assert_equal expected_name, MarkdownExec::SavedAsset.new(
|
79
|
+
blockname: blockname, filename: filename, prefix: prefix,
|
80
|
+
saved_asset_format: SAVED_ASSET_FORMAT, time: time
|
81
|
+
).generate_name
|
78
82
|
end
|
79
83
|
|
80
84
|
def test_stdout_name_with_special_characters_in_blockname
|
@@ -83,10 +87,11 @@ class SavedAssetTest < Minitest::Test
|
|
83
87
|
time = Time.new(2023, 1, 1, 12, 0, 0)
|
84
88
|
blockname = 'block/1:2'
|
85
89
|
|
86
|
-
expected_name = 'test_2023-01-01-12-00-00_sample_txt_
|
87
|
-
assert_equal expected_name, MarkdownExec::SavedAsset.
|
90
|
+
expected_name = 'test_2023-01-01-12-00-00_sample_txt_~_block_1_2_.*'
|
91
|
+
assert_equal expected_name, MarkdownExec::SavedAsset.new(
|
92
|
+
saved_asset_format: SAVED_ASSET_FORMAT,
|
88
93
|
filename: filename, prefix: prefix, time: time, blockname: blockname
|
89
|
-
)
|
94
|
+
).generate_name
|
90
95
|
end
|
91
96
|
|
92
97
|
def test_wildcard_name_with_all_parameters
|
@@ -94,11 +99,12 @@ class SavedAssetTest < Minitest::Test
|
|
94
99
|
prefix = 'test'
|
95
100
|
time = Time.new(2023, 1, 1, 12, 0, 0)
|
96
101
|
blockname = 'block/1:2'
|
97
|
-
expected_wildcard = 'test_2023-01-01-12-00-00_sample_txt_
|
102
|
+
expected_wildcard = 'test_2023-01-01-12-00-00_sample_txt_~_block_1_2_.*'
|
98
103
|
|
99
|
-
assert_equal expected_wildcard, MarkdownExec::SavedAsset.
|
104
|
+
assert_equal expected_wildcard, MarkdownExec::SavedAsset.new(
|
105
|
+
saved_asset_format: SAVED_ASSET_FORMAT,
|
100
106
|
filename: filename, prefix: prefix, time: time, blockname: blockname
|
101
|
-
)
|
107
|
+
).generate_name
|
102
108
|
end
|
103
109
|
|
104
110
|
def test_wildcard_name_with_missing_time
|
@@ -106,11 +112,12 @@ class SavedAssetTest < Minitest::Test
|
|
106
112
|
prefix = 'test'
|
107
113
|
time = nil
|
108
114
|
blockname = 'block/1:2'
|
109
|
-
expected_wildcard = 'test_*_sample_txt_
|
115
|
+
expected_wildcard = 'test_*_sample_txt_~_block_1_2_.*'
|
110
116
|
|
111
|
-
assert_equal expected_wildcard, MarkdownExec::SavedAsset.
|
117
|
+
assert_equal expected_wildcard, MarkdownExec::SavedAsset.new(
|
118
|
+
saved_asset_format: SAVED_ASSET_FORMAT,
|
112
119
|
filename: filename, prefix: prefix, time: time, blockname: blockname
|
113
|
-
)
|
120
|
+
).generate_name
|
114
121
|
end
|
115
122
|
|
116
123
|
def test_wildcard_name_with_missing_filename
|
@@ -118,11 +125,12 @@ class SavedAssetTest < Minitest::Test
|
|
118
125
|
prefix = 'test'
|
119
126
|
time = Time.new(2023, 1, 1, 12, 0, 0)
|
120
127
|
blockname = 'block/1:2'
|
121
|
-
expected_wildcard = 'test_2023-01-01-12-00-00_*_
|
128
|
+
expected_wildcard = 'test_2023-01-01-12-00-00_*_~_block_1_2_.*'
|
122
129
|
|
123
|
-
assert_equal expected_wildcard, MarkdownExec::SavedAsset.
|
130
|
+
assert_equal expected_wildcard, MarkdownExec::SavedAsset.new(
|
131
|
+
saved_asset_format: SAVED_ASSET_FORMAT,
|
124
132
|
filename: filename, prefix: prefix, time: time, blockname: blockname
|
125
|
-
)
|
133
|
+
).generate_name
|
126
134
|
end
|
127
135
|
|
128
136
|
def test_wildcard_name_with_missing_prefix
|
@@ -130,11 +138,12 @@ class SavedAssetTest < Minitest::Test
|
|
130
138
|
prefix = nil
|
131
139
|
time = Time.new(2023, 1, 1, 12, 0, 0)
|
132
140
|
blockname = 'block/1:2'
|
133
|
-
expected_wildcard = '*_2023-01-01-12-00-00_sample_txt_
|
141
|
+
expected_wildcard = '*_2023-01-01-12-00-00_sample_txt_~_block_1_2_.*'
|
134
142
|
|
135
|
-
assert_equal expected_wildcard, MarkdownExec::SavedAsset.
|
143
|
+
assert_equal expected_wildcard, MarkdownExec::SavedAsset.new(
|
144
|
+
saved_asset_format: SAVED_ASSET_FORMAT,
|
136
145
|
filename: filename, prefix: prefix, time: time, blockname: blockname
|
137
|
-
)
|
146
|
+
).generate_name
|
138
147
|
end
|
139
148
|
|
140
149
|
def test_wildcard_name_with_missing_blockname
|
@@ -142,11 +151,12 @@ class SavedAssetTest < Minitest::Test
|
|
142
151
|
prefix = 'test'
|
143
152
|
time = Time.new(2023, 1, 1, 12, 0, 0)
|
144
153
|
blockname = nil
|
145
|
-
expected_wildcard = 'test_2023-01-01-12-00-00_sample_txt_
|
154
|
+
expected_wildcard = 'test_2023-01-01-12-00-00_sample_txt_~_*_.*'
|
146
155
|
|
147
|
-
assert_equal expected_wildcard, MarkdownExec::SavedAsset.
|
156
|
+
assert_equal expected_wildcard, MarkdownExec::SavedAsset.new(
|
157
|
+
saved_asset_format: SAVED_ASSET_FORMAT,
|
148
158
|
filename: filename, prefix: prefix, time: time, blockname: blockname
|
149
|
-
)
|
159
|
+
).generate_name
|
150
160
|
end
|
151
161
|
|
152
162
|
def test_wildcard_name_with_all_missing
|
@@ -154,10 +164,11 @@ class SavedAssetTest < Minitest::Test
|
|
154
164
|
prefix = nil
|
155
165
|
time = nil
|
156
166
|
blockname = nil
|
157
|
-
expected_wildcard = '*_*_*_
|
167
|
+
expected_wildcard = '*_*_*_~_*_.*'
|
158
168
|
|
159
|
-
assert_equal expected_wildcard, MarkdownExec::SavedAsset.
|
169
|
+
assert_equal expected_wildcard, MarkdownExec::SavedAsset.new(
|
170
|
+
saved_asset_format: SAVED_ASSET_FORMAT,
|
160
171
|
filename: filename, prefix: prefix, time: time, blockname: blockname
|
161
|
-
)
|
172
|
+
).generate_name
|
162
173
|
end
|
163
174
|
end
|
data/lib/saved_files_matcher.rb
CHANGED
@@ -45,15 +45,18 @@ if $PROGRAM_NAME == __FILE__
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def test_list_all
|
48
|
-
assert_kind_of Array,
|
48
|
+
assert_kind_of Array,
|
49
|
+
MarkdownExec::SavedFilesMatcher.list_all(@folder, @glob)
|
49
50
|
end
|
50
51
|
|
51
52
|
def test_most_recent
|
52
|
-
assert_match(/\.md$/,
|
53
|
+
assert_match(/\.md$/,
|
54
|
+
MarkdownExec::SavedFilesMatcher.most_recent(@folder, @glob))
|
53
55
|
end
|
54
56
|
|
55
57
|
def test_most_recent_list
|
56
|
-
result = MarkdownExec::SavedFilesMatcher.most_recent_list(@folder, @glob,
|
58
|
+
result = MarkdownExec::SavedFilesMatcher.most_recent_list(@folder, @glob,
|
59
|
+
5)
|
57
60
|
assert_kind_of Array, result
|
58
61
|
assert_operator result.size, :<=, 16
|
59
62
|
end
|
data/lib/streams_out.rb
CHANGED
@@ -11,7 +11,13 @@ class StreamsOut
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def append_stream_line(stream, line)
|
14
|
-
@streams <<
|
14
|
+
@streams << OpenStruct.new(stream: stream, line: line, timestamp: Time.now)
|
15
|
+
end
|
16
|
+
|
17
|
+
def stream_lines(stream)
|
18
|
+
@streams.select do |v|
|
19
|
+
v[:stream] == stream
|
20
|
+
end.map(&:line)
|
15
21
|
end
|
16
22
|
|
17
23
|
def write_execution_output_to_file(filespec)
|