rundoc 4.0.0 → 4.1.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/.gitignore +1 -0
- data/CHANGELOG.md +8 -0
- data/README.md +62 -0
- data/lib/rundoc/cli.rb +2 -2
- data/lib/rundoc/code_command/file_command/append.rb +3 -1
- data/lib/rundoc/code_command/file_command/remove.rb +4 -1
- data/lib/rundoc/code_command/pre/erb.rb +63 -0
- data/lib/rundoc/code_command/print/erb.rb +5 -5
- data/lib/rundoc/code_command/rundoc/require.rb +1 -1
- data/lib/rundoc/code_command/write.rb +3 -1
- data/lib/rundoc/code_command.rb +1 -0
- data/lib/rundoc/{parser.rb → document.rb} +12 -18
- data/lib/rundoc/fenced_code_block.rb +124 -0
- data/lib/rundoc/version.rb +1 -1
- data/lib/rundoc.rb +2 -2
- data/test/integration/pre_erb_test.rb +100 -0
- data/test/integration/print_test.rb +8 -8
- data/test/integration/require_test.rb +3 -3
- data/test/integration/website_test.rb +1 -1
- data/test/rundoc/code_section_test.rb +48 -40
- data/test/rundoc/parser_test.rb +3 -3
- data/test/rundoc/peg_parser_test.rb +0 -33
- data/test/rundoc/regex_test.rb +19 -69
- data/test/test_helper.rb +5 -6
- metadata +6 -4
- data/lib/rundoc/code_section.rb +0 -155
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 406f197901506713b700c1ff8511fb05904400f806c7dc9d1a134e2b04ab13ab
|
4
|
+
data.tar.gz: 5b09bdd1560879915be2b52f1f36a13626fe2edfd696a14e66f90d5849b999fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '089c0ed9bb56187b8d18ff8eb55662ddf88f592329c028ff24478723bf044e87e75fbc6c84e903bb34bb3e111134a48a6b54861d6af1eb0e2cb9dc533a812da4'
|
7
|
+
data.tar.gz: f616697430af9d1948d64a9a97a7902ccc3dfa8a61cc4bc4a5b7d3e109944ec50e1475b6889c1168fceba5a733b4d34adc5dd0d068ddff85fcfbff40ee2e8438
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
## HEAD
|
2
2
|
|
3
|
+
## 4.1.1
|
4
|
+
|
5
|
+
- Fix: Visibility forwarding for `pre.erb` was accidentally reversed, this is now fixed. (https://github.com/zombocom/rundoc/pull/93)
|
6
|
+
|
7
|
+
## 4.1.0
|
8
|
+
|
9
|
+
- Add: Rundoc command `pre.erb` command used for dynamically templating any command using ERB syntax. (https://github.com/zombocom/rundoc/pull/90)
|
10
|
+
|
3
11
|
## 4.0.0
|
4
12
|
|
5
13
|
- Add: Rundoc command `background.stdin_write` to send a string to a backtround process' STDIN. This allows driving REPL interfaces (https://github.com/zombocom/rundoc/pull/79)
|
data/README.md
CHANGED
@@ -73,6 +73,8 @@ This will generate a project folder with your project in it, and a markdown `REA
|
|
73
73
|
- Execute Bash Commands
|
74
74
|
- [$](#shell-commands)
|
75
75
|
- [fail.$](#shell-commands)
|
76
|
+
- Dynamic command templating
|
77
|
+
- [pre.erb](#preerb)
|
76
78
|
- Printing
|
77
79
|
- [print.text](#print)
|
78
80
|
- [print.erb](#print)
|
@@ -257,6 +259,66 @@ These custom commands are kept to a minimum, and for the most part behave as you
|
|
257
259
|
|
258
260
|
Running shell commands like this can be very powerful, you'll likely want more control of how you manipulate files in your project. To do this you can use the `file.` namespace:
|
259
261
|
|
262
|
+
## Dynamic command templating
|
263
|
+
|
264
|
+
Meta commands that produce no output but instead allow for generating commands via dynamic templates.
|
265
|
+
|
266
|
+
Current Commands:
|
267
|
+
|
268
|
+
- `pre.erb`
|
269
|
+
|
270
|
+
### pre.erb
|
271
|
+
|
272
|
+
Placing `pre.erb` in-front of another command will allow dynmaic templating via Ruby's [ERB](https://rubyapi.org/3.3/o/erb) syntax.
|
273
|
+
|
274
|
+
For example:
|
275
|
+
|
276
|
+
```
|
277
|
+
:::>> pre.erb $ echo "The answer to everything is <%= 6*7 %>"
|
278
|
+
```
|
279
|
+
|
280
|
+
When this runs, it will first replace the template with the result of the ERB. It would be the same as this:
|
281
|
+
|
282
|
+
```
|
283
|
+
:::>> $ echo "The answer to everything is 42"
|
284
|
+
```
|
285
|
+
|
286
|
+
The binding (variable and method scope) for `pre.erb` is shared across all executions and the default `print.erb` command. That means you can use it to persist data or logic and re-use it:
|
287
|
+
|
288
|
+
```ruby
|
289
|
+
:::-- print.erb <%
|
290
|
+
# Won't be rendered because it's using `--` visibility
|
291
|
+
def lol
|
292
|
+
"haha"
|
293
|
+
end
|
294
|
+
|
295
|
+
user = "Schneems"
|
296
|
+
%>
|
297
|
+
```
|
298
|
+
|
299
|
+
```
|
300
|
+
:::>> pre.erb $ echo <%= user %> said <%= lol() %> | tr '[:lower:]' '[:upper:]'
|
301
|
+
```
|
302
|
+
|
303
|
+
When run, this would produce:
|
304
|
+
|
305
|
+
```
|
306
|
+
$ echo Schneems said haha | tr '[:lower:]' '[:upper:]'
|
307
|
+
SCHNEEMS SAID HAHA
|
308
|
+
```
|
309
|
+
|
310
|
+
Multi-line commands are also supported
|
311
|
+
|
312
|
+
```
|
313
|
+
:::>> pre.erb file.write "lol.txt"
|
314
|
+
Super secret key:
|
315
|
+
<%= "#{key}" %>
|
316
|
+
```
|
317
|
+
|
318
|
+
The only thing to watch out for is if the resulting template contains a `:::>>` (or similar) rundoc marker at the beginning of the line; Rundoc will think it is a new command rather than a part of `pre.erb` template.
|
319
|
+
|
320
|
+
The visibility of the `pre.erb` is forwarded to whatever command is run.
|
321
|
+
|
260
322
|
## Print
|
261
323
|
|
262
324
|
Current commands:
|
data/lib/rundoc/cli.rb
CHANGED
@@ -157,7 +157,7 @@ module Rundoc
|
|
157
157
|
|
158
158
|
io.puts "## Working dir is #{execution_context.output_dir}"
|
159
159
|
Dir.chdir(execution_context.output_dir) do
|
160
|
-
parser = Rundoc::
|
160
|
+
parser = Rundoc::Document.new(
|
161
161
|
source_contents,
|
162
162
|
context: execution_context
|
163
163
|
)
|
@@ -203,7 +203,7 @@ module Rundoc
|
|
203
203
|
to: on_failure_dir
|
204
204
|
)
|
205
205
|
|
206
|
-
on_failure_dir.join("RUNDOC_FAILED.md").write(Rundoc::
|
206
|
+
on_failure_dir.join("RUNDOC_FAILED.md").write(Rundoc::Document.partial_result_to_doc)
|
207
207
|
end
|
208
208
|
|
209
209
|
private def on_success(output)
|
@@ -12,7 +12,9 @@ class Rundoc::CodeCommand::FileCommand
|
|
12
12
|
def to_md(env)
|
13
13
|
return unless render_command?
|
14
14
|
|
15
|
-
|
15
|
+
if env[:commands].any? { |c| c[:object].not_hidden? }
|
16
|
+
raise "Must call append in its own code section"
|
17
|
+
end
|
16
18
|
|
17
19
|
env[:before] << if @line_number
|
18
20
|
"In file `#{filename}`, on line #{@line_number} add:"
|
@@ -7,7 +7,10 @@ class Rundoc::CodeCommand::FileCommand
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def to_md(env)
|
10
|
-
|
10
|
+
if env[:commands].any? { |c| c[:object].not_hidden? }
|
11
|
+
raise "Must call remove in its own code section"
|
12
|
+
end
|
13
|
+
|
11
14
|
env[:before] << "In file `#{filename}` remove:"
|
12
15
|
env[:before] << NEWLINE
|
13
16
|
nil
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require_relative "../print/erb"
|
2
|
+
|
3
|
+
class Rundoc::CodeCommand
|
4
|
+
class PreErb < Rundoc::CodeCommand
|
5
|
+
def initialize(line)
|
6
|
+
@line = line
|
7
|
+
@binding = RUNDOC_ERB_BINDINGS[RUNDOC_DEFAULT_ERB_BINDING]
|
8
|
+
@code = nil
|
9
|
+
@command = nil
|
10
|
+
@template = nil
|
11
|
+
@render_delegate_result = nil
|
12
|
+
@render_delegate_command = nil
|
13
|
+
# Hide self, pass visibility onto delegate
|
14
|
+
@render_result = false
|
15
|
+
@render_command = false
|
16
|
+
end
|
17
|
+
|
18
|
+
# Visibility is injected by the parser, capture it and pass it to the delegate
|
19
|
+
def render_result=(value)
|
20
|
+
@render_delegate_result = value
|
21
|
+
end
|
22
|
+
|
23
|
+
def render_command=(value)
|
24
|
+
@render_delegate_command = value
|
25
|
+
end
|
26
|
+
|
27
|
+
def code
|
28
|
+
@code ||= begin
|
29
|
+
vis = +""
|
30
|
+
vis += @render_delegate_command ? ">" : "-"
|
31
|
+
vis += @render_delegate_result ? ">" : "-"
|
32
|
+
code = [@line, @contents]
|
33
|
+
.compact
|
34
|
+
.reject(&:empty?)
|
35
|
+
.join("\n")
|
36
|
+
@template = ":::#{vis} #{code}"
|
37
|
+
|
38
|
+
puts "pre.erb: Applying ERB, template:\n#{@template}"
|
39
|
+
result = ERB.new(@template).result(@binding)
|
40
|
+
puts "pre.erb: ERB result:\n#{result}"
|
41
|
+
puts "pre.erb: done, ready to delegate"
|
42
|
+
result
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def command
|
47
|
+
@command ||= Rundoc::FencedCodeBlock.parse_code_commands(code).first
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_md(env = {})
|
51
|
+
""
|
52
|
+
end
|
53
|
+
|
54
|
+
def call(env = {})
|
55
|
+
# Defer running ERB until as late as possible
|
56
|
+
delegate = command
|
57
|
+
# Delegate will be executed by the caller working through the stack
|
58
|
+
env[:stack].push(delegate)
|
59
|
+
""
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
Rundoc.register_code_command(:"pre.erb", Rundoc::CodeCommand::PreErb)
|
@@ -10,11 +10,12 @@ class EmptyBinding
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
RUNDOC_ERB_BINDINGS = Hash.new { |h, k| h[k] = EmptyBinding.create }
|
14
|
-
|
15
13
|
class Rundoc::CodeCommand
|
14
|
+
RUNDOC_ERB_BINDINGS = Hash.new { |h, k| h[k] = EmptyBinding.create }
|
15
|
+
RUNDOC_DEFAULT_ERB_BINDING = "default"
|
16
|
+
|
16
17
|
class PrintERB < Rundoc::CodeCommand
|
17
|
-
def initialize(line = nil, binding:
|
18
|
+
def initialize(line = nil, binding: RUNDOC_DEFAULT_ERB_BINDING)
|
18
19
|
@line = line
|
19
20
|
@binding = RUNDOC_ERB_BINDINGS[binding]
|
20
21
|
end
|
@@ -31,7 +32,7 @@ class Rundoc::CodeCommand
|
|
31
32
|
@render ||= ERB.new([@line, contents].compact.join("\n")).result(@binding)
|
32
33
|
end
|
33
34
|
|
34
|
-
def call(
|
35
|
+
def call(env = {})
|
35
36
|
if render_before?
|
36
37
|
""
|
37
38
|
else
|
@@ -44,5 +45,4 @@ class Rundoc::CodeCommand
|
|
44
45
|
end
|
45
46
|
end
|
46
47
|
end
|
47
|
-
|
48
48
|
Rundoc.register_code_command(:"print.erb", Rundoc::CodeCommand::PrintERB)
|
@@ -17,7 +17,7 @@ class ::Rundoc::CodeCommand
|
|
17
17
|
execution_context = env[:context]
|
18
18
|
document_path = @path.expand_path(execution_context.source_dir)
|
19
19
|
|
20
|
-
output = Rundoc::
|
20
|
+
output = Rundoc::Document.new(
|
21
21
|
document_path.read,
|
22
22
|
context: Rundoc::Context::Execution.new(
|
23
23
|
source_path: document_path,
|
@@ -24,7 +24,9 @@ module Rundoc
|
|
24
24
|
|
25
25
|
def to_md(env)
|
26
26
|
if render_command?
|
27
|
-
|
27
|
+
if env[:commands].any? { |c| c[:object].not_hidden? }
|
28
|
+
raise "must call write in its own code section"
|
29
|
+
end
|
28
30
|
env[:before] << "In file `#{filename}` write:"
|
29
31
|
env[:before] << NEWLINE
|
30
32
|
end
|
data/lib/rundoc/code_command.rb
CHANGED
@@ -1,25 +1,20 @@
|
|
1
1
|
module Rundoc
|
2
|
-
#
|
2
|
+
# Represents a single rundoc file on disk,
|
3
3
|
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
INDENT_BLOCK = '(?<before_indent>(^\s*$\n|\A)(^(?:[ ]{4}|\t))(?<indent_contents>.*)(?<after_indent>[^\s].*$\n?(?:(?:^\s*$\n?)*^(?:[ ]{4}|\t).*[^\s].*$\n?)*))'
|
4
|
+
# Each document contains one or more fenced code blocks.
|
5
|
+
# Those are parsed as `FencedCodeBlock` instances and then
|
6
|
+
# executed.
|
7
|
+
class Document
|
9
8
|
GITHUB_BLOCK = '^(?<fence>(?<fence_char>~|`){3,})\s*?(?<lang>\w+)?\s*?\n(?<contents>.*?)^\g<fence>\g<fence_char>*\s*?\n?'
|
10
9
|
CODEBLOCK_REGEX = /(#{GITHUB_BLOCK})/m
|
11
|
-
COMMAND_REGEX = ->(keyword) {
|
12
|
-
/^#{keyword}(?<tag>(\s|=|-|>)?(=|-|>)?)\s*(?<command>(\S)+)\s+(?<statement>.*)$/
|
13
|
-
}
|
14
10
|
PARTIAL_RESULT = []
|
15
11
|
|
16
|
-
attr_reader :contents, :
|
12
|
+
attr_reader :contents, :stack, :context
|
17
13
|
|
18
|
-
def initialize(contents, context
|
14
|
+
def initialize(contents, context:)
|
19
15
|
@context = context
|
20
16
|
@contents = contents
|
21
17
|
@original = contents.dup
|
22
|
-
@keyword = keyword
|
23
18
|
@stack = []
|
24
19
|
partition
|
25
20
|
PARTIAL_RESULT.clear
|
@@ -44,7 +39,7 @@ module Rundoc
|
|
44
39
|
|
45
40
|
def self.partial_result_to_doc
|
46
41
|
out = to_doc(result: PARTIAL_RESULT)
|
47
|
-
unfinished =
|
42
|
+
unfinished = FencedCodeBlock.partial_result_to_doc
|
48
43
|
out << unfinished if unfinished
|
49
44
|
out
|
50
45
|
end
|
@@ -60,9 +55,10 @@ module Rundoc
|
|
60
55
|
@stack << head unless head.empty?
|
61
56
|
unless code.empty?
|
62
57
|
match = code.match(CODEBLOCK_REGEX)
|
63
|
-
@stack <<
|
64
|
-
match,
|
65
|
-
|
58
|
+
@stack << FencedCodeBlock.new(
|
59
|
+
fence: match[:fence],
|
60
|
+
lang: match[:lang],
|
61
|
+
code: match[:contents],
|
66
62
|
context: context
|
67
63
|
)
|
68
64
|
end
|
@@ -71,5 +67,3 @@ module Rundoc
|
|
71
67
|
end
|
72
68
|
end
|
73
69
|
end
|
74
|
-
|
75
|
-
# convert string of markdown to array of strings and code_command
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rundoc
|
4
|
+
# A code secttion respesents a block of fenced code
|
5
|
+
#
|
6
|
+
# A document can have multiple code sections
|
7
|
+
class FencedCodeBlock
|
8
|
+
AUTOGEN_WARNING = "\n<!-- STOP. This document is autogenerated. Do not manually modify. See the top of the doc for more details. -->"
|
9
|
+
attr_accessor :fence, :lang, :code
|
10
|
+
|
11
|
+
PARTIAL_RESULT = []
|
12
|
+
PARTIAL_ENV = {}
|
13
|
+
|
14
|
+
# Used for tests to inspect the command that was executed
|
15
|
+
def executed_commands
|
16
|
+
raise "Nothing executed" unless @env[:commands].any?
|
17
|
+
|
18
|
+
@env[:commands].map { |c| c[:object] }
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param fence [String] the fence used to start the code block like "```".
|
22
|
+
# @param lang [String] any extra string after the fence like for example
|
23
|
+
# a fence of "```ruby" the lang would be "ruby".
|
24
|
+
# @param code [String] the code block contents inside the fence.
|
25
|
+
# @param context [Context::Execution] The details about where
|
26
|
+
# the code block came from.
|
27
|
+
def initialize(fence:, lang:, code:, context:)
|
28
|
+
@fence = fence
|
29
|
+
@lang = lang
|
30
|
+
@code = code
|
31
|
+
@executed = false
|
32
|
+
@env = {}
|
33
|
+
@stack = []
|
34
|
+
@context = context
|
35
|
+
@rendered = ""
|
36
|
+
self.class.parse_code_commands(@code).each do |code_command|
|
37
|
+
@stack.unshift(code_command)
|
38
|
+
end
|
39
|
+
|
40
|
+
PARTIAL_RESULT.clear
|
41
|
+
PARTIAL_ENV.clear
|
42
|
+
end
|
43
|
+
|
44
|
+
def call
|
45
|
+
return self if @executed
|
46
|
+
@executed = true
|
47
|
+
|
48
|
+
result = []
|
49
|
+
env = @env
|
50
|
+
env[:commands] = []
|
51
|
+
env[:fence_start] = "#{fence}#{lang}"
|
52
|
+
env[:fence_end] = "#{fence}#{AUTOGEN_WARNING}"
|
53
|
+
env[:before] = []
|
54
|
+
env[:after] = []
|
55
|
+
env[:context] = @context
|
56
|
+
env[:stack] = @stack
|
57
|
+
|
58
|
+
while (code_command = @stack.pop)
|
59
|
+
code_output = code_command.call(env) || ""
|
60
|
+
code_line = code_command.to_md(env) || ""
|
61
|
+
result << code_line if code_command.render_command?
|
62
|
+
result << code_output if code_command.render_result?
|
63
|
+
|
64
|
+
PARTIAL_RESULT.replace(result)
|
65
|
+
PARTIAL_ENV.replace(env)
|
66
|
+
|
67
|
+
env[:commands] << {
|
68
|
+
object: code_command,
|
69
|
+
output: code_output,
|
70
|
+
command: code_line
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
if env[:commands].any? { |c| c[:object].not_hidden? }
|
75
|
+
@rendered = self.class.to_doc(result: result, env: env)
|
76
|
+
end
|
77
|
+
self
|
78
|
+
end
|
79
|
+
|
80
|
+
def render
|
81
|
+
call
|
82
|
+
@rendered
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.partial_result_to_doc
|
86
|
+
to_doc(result: PARTIAL_RESULT, env: PARTIAL_ENV)
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.to_doc(result:, env:)
|
90
|
+
array = [env[:before]]
|
91
|
+
|
92
|
+
result.flatten!
|
93
|
+
result.compact!
|
94
|
+
result.map! { |s| s.respond_to?(:rstrip) ? s.rstrip : s }
|
95
|
+
result.reject!(&:empty?)
|
96
|
+
result.map!(&:to_s)
|
97
|
+
|
98
|
+
if !result.empty?
|
99
|
+
array << env[:fence_start]
|
100
|
+
array << result
|
101
|
+
array << env[:fence_end]
|
102
|
+
end
|
103
|
+
array << env[:after]
|
104
|
+
|
105
|
+
array.flatten!
|
106
|
+
array.compact!
|
107
|
+
array.map! { |s| s.respond_to?(:rstrip) ? s.rstrip : s }
|
108
|
+
array.reject!(&:empty?)
|
109
|
+
array.map!(&:to_s)
|
110
|
+
|
111
|
+
array.join("\n") << "\n"
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.parse_code_commands(code)
|
115
|
+
parser = Rundoc::PegParser.new.code_block
|
116
|
+
tree = parser.parse(code)
|
117
|
+
commands = Rundoc::PegTransformer.new.apply(tree)
|
118
|
+
commands = [commands] unless commands.is_a?(Array)
|
119
|
+
commands
|
120
|
+
rescue ::Parslet::ParseFailed => e
|
121
|
+
raise "Could not compile code:\n#{code}\nReason: #{e.message}"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
data/lib/rundoc/version.rb
CHANGED
data/lib/rundoc.rb
CHANGED
@@ -87,8 +87,8 @@ module Rundoc
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
-
require "rundoc/
|
91
|
-
require "rundoc/
|
90
|
+
require "rundoc/document"
|
91
|
+
require "rundoc/fenced_code_block"
|
92
92
|
require "rundoc/code_command"
|
93
93
|
require "rundoc/peg_parser"
|
94
94
|
require "rundoc/cli_argument_parser"
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class IntegrationPreErb < Minitest::Test
|
4
|
+
def test_result_visibility_forwarding
|
5
|
+
contents = <<~RUBY
|
6
|
+
```
|
7
|
+
:::-> pre.erb $ echo <%= 1 + 1 %>
|
8
|
+
```
|
9
|
+
RUBY
|
10
|
+
|
11
|
+
Dir.mktmpdir do |dir|
|
12
|
+
Dir.chdir(dir) do
|
13
|
+
expected = <<~EOF
|
14
|
+
```
|
15
|
+
2
|
16
|
+
```
|
17
|
+
EOF
|
18
|
+
|
19
|
+
parsed = parse_contents(contents)
|
20
|
+
actual = parsed.to_md.gsub(Rundoc::FencedCodeBlock::AUTOGEN_WARNING, "").strip
|
21
|
+
assert_equal expected.strip, actual.strip
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_command_visibility_forwarding
|
27
|
+
contents = <<~RUBY
|
28
|
+
```
|
29
|
+
:::>- pre.erb $ echo <%= 1 + 1 %>
|
30
|
+
```
|
31
|
+
RUBY
|
32
|
+
|
33
|
+
Dir.mktmpdir do |dir|
|
34
|
+
Dir.chdir(dir) do
|
35
|
+
expected = <<~EOF
|
36
|
+
```
|
37
|
+
$ echo 2
|
38
|
+
```
|
39
|
+
EOF
|
40
|
+
|
41
|
+
parsed = parse_contents(contents)
|
42
|
+
actual = parsed.to_md.gsub(Rundoc::FencedCodeBlock::AUTOGEN_WARNING, "").strip
|
43
|
+
assert_equal expected.strip, actual.strip
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_file_write
|
49
|
+
key = SecureRandom.hex
|
50
|
+
contents = <<~RUBY
|
51
|
+
```
|
52
|
+
:::>> pre.erb file.write "lol.txt"
|
53
|
+
Multi line
|
54
|
+
<%= "#{key}" %>
|
55
|
+
```
|
56
|
+
RUBY
|
57
|
+
|
58
|
+
Dir.mktmpdir do |dir|
|
59
|
+
Dir.chdir(dir) do
|
60
|
+
expected = <<~EOF
|
61
|
+
In file `lol.txt` write:
|
62
|
+
|
63
|
+
```
|
64
|
+
Multi line
|
65
|
+
#{key}
|
66
|
+
```
|
67
|
+
EOF
|
68
|
+
|
69
|
+
parsed = parse_contents(contents)
|
70
|
+
actual = parsed.to_md.gsub(Rundoc::FencedCodeBlock::AUTOGEN_WARNING, "").strip
|
71
|
+
assert_equal expected.strip, actual.strip
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_erb_shared_binding_persists_values
|
77
|
+
key = SecureRandom.hex
|
78
|
+
contents = <<~RUBY
|
79
|
+
```
|
80
|
+
:::-- print.erb <% secret = "#{key}" %>
|
81
|
+
:::>> pre.erb $ echo <%= secret %>
|
82
|
+
```
|
83
|
+
RUBY
|
84
|
+
|
85
|
+
Dir.mktmpdir do |dir|
|
86
|
+
Dir.chdir(dir) do
|
87
|
+
expected = <<~EOF
|
88
|
+
```
|
89
|
+
$ echo #{key}
|
90
|
+
#{key}
|
91
|
+
```
|
92
|
+
EOF
|
93
|
+
|
94
|
+
parsed = parse_contents(contents)
|
95
|
+
actual = parsed.to_md.gsub(Rundoc::FencedCodeBlock::AUTOGEN_WARNING, "").strip
|
96
|
+
assert_equal expected.strip, actual.strip
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -21,7 +21,7 @@ class IntegrationPrintTest < Minitest::Test
|
|
21
21
|
#{key}
|
22
22
|
EOF
|
23
23
|
parsed = parse_contents(contents)
|
24
|
-
actual = parsed.to_md.gsub(Rundoc::
|
24
|
+
actual = parsed.to_md.gsub(Rundoc::FencedCodeBlock::AUTOGEN_WARNING, "")
|
25
25
|
assert_equal expected, actual
|
26
26
|
end
|
27
27
|
end
|
@@ -44,7 +44,7 @@ class IntegrationPrintTest < Minitest::Test
|
|
44
44
|
one
|
45
45
|
EOF
|
46
46
|
parsed = parse_contents(contents)
|
47
|
-
actual = parsed.to_md.gsub(Rundoc::
|
47
|
+
actual = parsed.to_md.gsub(Rundoc::FencedCodeBlock::AUTOGEN_WARNING, "")
|
48
48
|
assert_equal expected, actual
|
49
49
|
end
|
50
50
|
end
|
@@ -70,7 +70,7 @@ class IntegrationPrintTest < Minitest::Test
|
|
70
70
|
```
|
71
71
|
EOF
|
72
72
|
parsed = parse_contents(contents)
|
73
|
-
actual = parsed.to_md.gsub(Rundoc::
|
73
|
+
actual = parsed.to_md.gsub(Rundoc::FencedCodeBlock::AUTOGEN_WARNING, "")
|
74
74
|
assert_equal expected, actual
|
75
75
|
end
|
76
76
|
end
|
@@ -94,7 +94,7 @@ class IntegrationPrintTest < Minitest::Test
|
|
94
94
|
there
|
95
95
|
EOF
|
96
96
|
parsed = parse_contents(contents)
|
97
|
-
actual = parsed.to_md.gsub(Rundoc::
|
97
|
+
actual = parsed.to_md.gsub(Rundoc::FencedCodeBlock::AUTOGEN_WARNING, "")
|
98
98
|
assert_equal expected, actual
|
99
99
|
end
|
100
100
|
end
|
@@ -118,7 +118,7 @@ class IntegrationPrintTest < Minitest::Test
|
|
118
118
|
there
|
119
119
|
EOF
|
120
120
|
parsed = parse_contents(contents)
|
121
|
-
actual = parsed.to_md.gsub(Rundoc::
|
121
|
+
actual = parsed.to_md.gsub(Rundoc::FencedCodeBlock::AUTOGEN_WARNING, "")
|
122
122
|
assert_equal expected, actual
|
123
123
|
end
|
124
124
|
end
|
@@ -142,7 +142,7 @@ class IntegrationPrintTest < Minitest::Test
|
|
142
142
|
there
|
143
143
|
EOF
|
144
144
|
parsed = parse_contents(contents)
|
145
|
-
actual = parsed.to_md.gsub(Rundoc::
|
145
|
+
actual = parsed.to_md.gsub(Rundoc::FencedCodeBlock::AUTOGEN_WARNING, "")
|
146
146
|
assert_equal expected, actual
|
147
147
|
end
|
148
148
|
end
|
@@ -163,7 +163,7 @@ class IntegrationPrintTest < Minitest::Test
|
|
163
163
|
Hello there
|
164
164
|
EOF
|
165
165
|
parsed = parse_contents(contents)
|
166
|
-
actual = parsed.to_md.gsub(Rundoc::
|
166
|
+
actual = parsed.to_md.gsub(Rundoc::FencedCodeBlock::AUTOGEN_WARNING, "")
|
167
167
|
assert_equal expected, actual
|
168
168
|
end
|
169
169
|
end
|
@@ -186,7 +186,7 @@ class IntegrationPrintTest < Minitest::Test
|
|
186
186
|
```
|
187
187
|
EOF
|
188
188
|
parsed = parse_contents(contents)
|
189
|
-
actual = parsed.to_md.gsub(Rundoc::
|
189
|
+
actual = parsed.to_md.gsub(Rundoc::FencedCodeBlock::AUTOGEN_WARNING, "")
|
190
190
|
assert_equal expected, actual
|
191
191
|
end
|
192
192
|
end
|
@@ -22,7 +22,7 @@ class IntegrationRequireTest < Minitest::Test
|
|
22
22
|
source_path.read,
|
23
23
|
source_path: source_path
|
24
24
|
)
|
25
|
-
actual = parsed.to_md.gsub(Rundoc::
|
25
|
+
actual = parsed.to_md.gsub(Rundoc::FencedCodeBlock::AUTOGEN_WARNING, "")
|
26
26
|
assert_equal "Hello World!", actual.strip
|
27
27
|
end
|
28
28
|
end
|
@@ -50,7 +50,7 @@ class IntegrationRequireTest < Minitest::Test
|
|
50
50
|
source_path.read,
|
51
51
|
source_path: source_path
|
52
52
|
)
|
53
|
-
actual = parsed.to_md.gsub(Rundoc::
|
53
|
+
actual = parsed.to_md.gsub(Rundoc::FencedCodeBlock::AUTOGEN_WARNING, "")
|
54
54
|
# Command was run
|
55
55
|
assert dir.join("foo.txt").exist?
|
56
56
|
assert "echo hello world", dir.join("foo.txt").read.strip
|
@@ -89,7 +89,7 @@ class IntegrationRequireTest < Minitest::Test
|
|
89
89
|
source_path.read,
|
90
90
|
source_path: source_path
|
91
91
|
)
|
92
|
-
actual = parsed.to_md.gsub(Rundoc::
|
92
|
+
actual = parsed.to_md.gsub(Rundoc::FencedCodeBlock::AUTOGEN_WARNING, "")
|
93
93
|
assert_equal "Hello World!", actual.strip
|
94
94
|
end
|
95
95
|
end
|